【9929】潜水员
Time Limit: 1 second
Memory Limit: 128 MB
【問題描述】
潛水員為了潛水要使用特殊的裝備。他有一個帶2種氣體的氣缸:一個為氧氣,一個為氮氣。讓潛水員下潛的深度需要各種的數量
的氧和氮。潛水員有一定數量的氣缸。每個氣缸都有重量和氣體容量。潛水員為了完成他的工作需要特定數量的氧和氮。他完
成工作所需氣缸的總重的最低限度的是多少?
例如:潛水員有5個氣缸。每行三個數字為:氧,氮的(升)量和氣缸的重量:
3 36 120
10 25 129
5 50 250
1 45 130
4 20 119
如果潛水員需要5升的氧和60升的氮則總重最小為249(1,2或者4,5號氣缸)。
你的任務就是計算潛水員為了完成他的工作需要的氣缸的重量的最低值。
【輸入格式】
第一行有2整數m,n(1<=m<=21,1<=n<=79)。它們表示氧,氮各自需要的量。
第二行為整數k(1<=n<=1000)表示氣缸的個數。
此后的k行,每行包括ai,bi,ci(1<=ai<=21,1<=bi<=79,1<=ci<=800)3整數。這些各自是:第i個氣缸里的氧和氮的容量及
汽缸重量。
【輸出格式】
僅一行包含一個整數,為潛水員完成工作所需的氣缸的重量總和的最低值。
Sample Input
5 60 5 3 36 120 10 25 129 5 50 250 1 45 130 4 20 119
Sample Output
249
【題解】
對于每一個氣缸。都有選或不選兩種可能。也即0/1背包。但是這次不再是所用的花費不大于X的問題了。
而應該是剛好為X,或者到達了要求之后,大于等于X的問題。比如你要5單位的氧氣。你不能說含有不超過
5單位氧氣的最大花費,而應該說恰為5單位,或者給6單位也可以。大于5就直接讓他等于5就可以了。
然后因為是0/1背包。更新的話要逆序更新。
這種恰好問題。要置其他f[i][j](二維費用)為一個很大的數,然后f[0][0] =0 ,表示0氧氣,0氮氣,
不需要氣缸。所以重量為0;從f[0][0]開始得到其他值。
【代碼】
#include <cstdio> int mo2,mn2,n,wo2[1010],wn2[1010],weight[1010],f[100][100]; void input_data() { scanf("%d%d",&mo2,&mn2); scanf("%d",&n); for (int i = 1;i <= n;i++) scanf("%d%d%d",&wo2[i],&wn2[i],&weight[i]); } void get_ans() { for (int i = 0;i <=mo2;i++) for (int j = 0;j <= mn2;j++) f[i][j] = 2100000000 / 3; //把其他f[i][j]置為一個很大的值 f[0][0] = 0; //0氧氣0氮氣的重量為0 for (int i = 1;i <= n;i++) for (int j = mo2 + wo2[i];j >= wo2[i];j--) //因為大于所需的值也是符合要求的 for (int k = mn2 + wn2[i];k >= wn2[i];k--) { int mm = j; if (j > mo2) //如果j是大于所需值,就讓他為所需值就好 mm = mo2; int nn = k; if (k > mn2) nn = mn2; if (f[mm][nn] > f[j-wo2[i]][k-wn2[i]] + weight[i]) //嘗試更新解。 f[mm][nn] = f[j-wo2[i]][k-wn2[i]] + weight[i]; } } void output_ans() { printf("%d",f[mo2][mn2]); //最后輸出f[mo2][mn2]表示達到所需值,所花費的最少重量 } int main() { //freopen("F:\rush.txt","r",stdin); input_data(); get_ans(); output_ans(); return 0; }
總結
- 上一篇: axios 重新发起上次请求
- 下一篇: 移动平台商家支付宝如何获取商户私钥,支付