P1757 通天之分组背包
P1757 通天之分组背包
背包中的经典问题,我竟然不知道。
分组背包
就是每个物品有一个所属的小组,小组内的物品会冲突。
就是把01背包中的两个for换一下位置
01:
for(i,1,kind)
for(j,v,w[i])
分组背包
for(j,v,w[i])
for(i,1,kind)
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath> 6 #include<ctime> 7 #include<cstring> 8 #define inf 2147483647 9 #define For(i,a,b) for(register int i=a;i<=b;i++) 10 #define p(a) putchar(a) 11 #define g() getchar() 12 //by war 13 //2017.10.17 14 using namespace std; 15 int n,m,x,y,z; 16 struct bag 17 { 18 int cnt; 19 int v[1010]; 20 int w[1010]; 21 }a[110]; 22 int f[1010]; 23 bool b[110]; 24 int kind; 25 int ans; 26 void in(int &x) 27 { 28 int y=1; 29 char c=g();x=0; 30 while(c<'0'||c>'9') 31 { 32 if(c=='-') 33 y=-1; 34 c=g(); 35 } 36 while(c<='9'&&c>='0')x=x*10+c-'0',c=g(); 37 x*=y; 38 } 39 void o(int x) 40 { 41 if(x<0) 42 { 43 p('-'); 44 x=-x; 45 } 46 if(x>9)o(x/10); 47 p(x%10+'0'); 48 } 49 int main() 50 { 51 in(m),in(n); 52 For(i,1,n) 53 { 54 in(x),in(y),in(z); 55 if(!b[z]) 56 { 57 kind++; 58 b[z]=true; 59 } 60 a[z].cnt++; 61 a[z].v[a[z].cnt]=y; 62 a[z].w[a[z].cnt]=x; 63 } 64 For(i,1,kind) 65 { 66 for(int t=m;t>=0;t--) 67 For(j,1,a[i].cnt) 68 if(t>=a[i].w[j]) 69 f[t]=max(f[t],f[t-a[i].w[j]]+a[i].v[j]); 70 } 71 o(f[m]); 72 return 0; 73 }