只要找到什麼代表時間,什麼代表重量,就能解。
解題想法
依序考慮每個物品放或不放到背包,若放到背包後,形成更大的價值就放入背包中。
Step 1
依序考慮每個物品,考慮第i個物品是否要加入背包。假設第i個物品重x公斤、背包裡的物品共t公斤重,若(t公斤物品的總價值 + 第i個物品的價值 ) > 原本t+x公斤物品的總價值 ,則將原本t+x公斤物品的總價值 更新成t公斤物品的總價值+第i個物品的價值 。
Step 2
使用陣列k儲存各個負重重量的最大價值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include<iostream> #include<cstring> using namespace std;
int v[101],c[101],t[101];
int main(){ int n,i,j; while(cin>>n){ memset(t,0,sizeof(t)); for(i=0;i<n;i++){cin>>v[i]>>c[i];} for(i=0;i<n;i++){ for(j=100;j>=v[i];j--){ if(t[j-v[i]]+c[i]>t[j]){t[j]=t[j-v[i]]+c[i];} } } cout<<t[100]<<endl; } return 0; }
|
這題的測資量不大,可以選擇窮舉或是用01背包解。用背包的話,我們可以開一個陣列l[1001]代表這是一個可以裝長度1000的背包 ,然後l[n]代表容量為長度n的背包最多能放多長的bar ,意思就是我們用長度代替背包的容量以及物品總價值,決定好所有東西該放還不該放後,最後就看l[n]的值是否為n,是的話輸出yes,否則no。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include<stdio.h> #include<stdlib.h> #define max(a,b) a>b?a:b
int main(){ int t,n,p,i,j,x; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&p); int l[1001]={0}; for(i=0;i<p;i++){ scanf("%d",&x); for(j=n;j>=x;j--){ l[j] = max(l[j], l[j-x]+x); } } if(l[n] == n){printf("YES\n");} else{printf("NO\n");} } return 0; }
|
雖然不知道每行輸入的這N個正整數的範圍,不過總和好像不會超過十萬,那我用背包做就不會有陣列開太大而報錯的問題 ,而且也會比窮舉(2^100)快。
又上榜了!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #include<stdio.h> #define max(a,b) a>b?a:b
int main(){ int m,n,i,j; while(scanf("%d%d",&n,&m) != EOF){ while(n--){ int a[m],cpct=0; for(i=0;i<m;i++){ scanf("%d",&a[i]); cpct+=a[i]; }
if(cpct%2==1){ printf("No\n"); continue; } int tmp=cpct/2, bp[tmp+1]; for(i=0;i<tmp+1;i++){ bp[i] = 0; }
for(i=0;i<m;i++){ for(j=tmp ; j>=a[i] ; j--){ bp[j] = max(bp[j], bp[ j-a[i] ] + a[i]); } }
if(bp[tmp] == tmp){ printf("Yes\n"); } else{ printf("No\n"); } } } return 0; }
|
看到題目中出現了我母校的背包,就知道這題要用背包解法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include<stdio.h> #define max(a,b) a>b?a:b
int main(){ int n,i,j,l,ta,tb; while(scanf("%d",&n) != EOF){ int bp[10001]={0},w[100],v[100]; for(i=0;i<n;i++){ scanf("%d%d",&w[i],&v[i]); } scanf("%d",&l); for(i=0 ; i<n ; i++){ ta = w[i];tb = v[i]; for(j=l ; j>=ta ; j--){ bp[j] = max(bp[j],bp[j-ta]+tb); } } printf("%d\n",bp[l]); } return 0; }
|
這題的話把時間當成物品重量,然後價值就是價值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include<stdio.h> #define max(a,b) a>b?a:b
int main(){ int t,m,i,time,v; while(scanf("%d%d",&t,&m) != EOF){ int bp[1001]={0}; while(m--){ scanf("%d%d",&time,&v); for(i=t;i>=time;i--){ bp[i] = max(bp[i],bp[i-time]+v); } } printf("%d\n",bp[t]); } return 0; }
|
封面圖源:Future Lab FreeZone X 獨創零負重背包