题意:
题解:
多重背包
转01背包,二进制分下组,压压常,轻松水过......
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
#define RG register
#define N 1650
#define M 40010
using namespace std;
int a[N],b[N],dfn[N],dp[M];
inline int gi() {
int x=0,o=1; char ch=getchar();
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') o=-1,ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return o*x;
}
inline bool cmp(int x, int y) {
return b[x]<b[y];
}
int main() {
RG int n=gi(),m=0,cnt=0;
for(RG int i=1; i<=n; i++) {
int x=gi(),y=gi(),z=gi(),k;
for(RG int j=1; z; j<<=1) {
k=min(j,z),z-=k;
a[++cnt]=k*x,b[cnt]=y;
}
m=max(m,y);
}
for(RG int i=1; i<=cnt; i++) dfn[i]=i;
sort(dfn+1,dfn+cnt+1,cmp);
dp[0]=1;
for(RG int i=1; i<=cnt; i++) {
int u=dfn[i];
for(RG int j=b[u]; j>=0; j--) {
if(j-a[u]>=0) {
dp[j]|=dp[j-a[u]];
}
}
}
for(int i=m; i>=0; i--) {
if(dp[i]) {
printf("%d
", i);
break;
}
}
return 0;
}