只要找到什麼代表時間,什麼代表重量,就能解。

b184: 5. 裝貨櫃問題

解題想法

依序考慮每個物品放或不放到背包,若放到背包後,形成更大的價值就放入背包中。

Step 1
依序考慮每個物品,考慮第i個物品是否要加入背包。假設第i個物品重x公斤、背包裡的物品共t公斤重,若(t公斤物品的總價值 + 第i個物品的價值 ) > 原本t+x公斤物品的總價值 ,則將原本t+x公斤物品的總價值 更新成t公斤物品的總價值+第i個物品的價值
Step 2
使用陣列k儲存各個負重重量的最大價值。

AC (2ms, 312KB)

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;
}

a522. 12455 - Bars

這題的測資量不大,可以選擇窮舉或是用01背包解。用背包的話,我們可以開一個陣列l[1001]代表這是一個可以裝長度1000的背包 ,然後l[n]代表容量為長度n的背包最多能放多長的bar ,意思就是我們用長度代替背包的容量以及物品總價值,決定好所有東西該放還不該放後,最後就看l[n]的值是否為n,是的話輸出yes,否則no。

AC (2ms, 84KB)

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;
}

b116: TOI2008 3. 加減問題

雖然不知道每行輸入的這N個正整數的範圍,不過總和好像不會超過十萬,那我用背包做就不會有陣列開太大而報錯的問題 ,而且也會比窮舉(2^100)快。

AC (3ms, 84KB)

又上榜了!

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];
}

//數列總和為奇數,則怎麼加減都不會剛好為0。
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]);
}
}

//輸出Yes或No
if(bp[tmp] == tmp){
printf("Yes\n");
}
else{
printf("No\n");
}
}
}
return 0;
}

a587. 祖靈好孝順 ˋˇˊ

看到題目中出現了我母校的背包,就知道這題要用背包解法。

AC (0.2s, 116KB)

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;
}

b140. NOIP2005 3.采药

這題的話把時間當成物品重量,然後價值就是價值。

AC (5ms, 88KB)

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 獨創零負重背包