https://www.luogu.org/problemnew/show/P2623
https://www.luogu.org/blog/test-1/solution-p2623
重点就是甲类物品最多取一个,一定能取到最优解。。。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #define fi first 7 #define se second 8 #define mp make_pair 9 #define pb push_back 10 typedef long long ll; 11 typedef unsigned long long ull; 12 typedef pair<ll,ll> pll; 13 14 ll ans[2005],an2; 15 //前i个物品,用j的容量的最大价值 16 vector<pll> dd; 17 ll n,m; 18 int main() 19 { 20 ll idx,i,j,k,a,b,c; 21 scanf("%lld%lld",&n,&m); 22 for(i=1;i<=n;i++) 23 { 24 scanf("%lld",&idx); 25 if(idx==1) 26 { 27 scanf("%lld%lld",&a,&b); 28 dd.pb(mp(a,b)); 29 } 30 else if(idx==2) 31 { 32 scanf("%lld%lld%lld",&a,&b,&c); 33 if(b==0) 34 { 35 for(j=0;j<=m;j++) ans[j]+=a*c; 36 } 37 else 38 { 39 for(j=m;j>=1;j--) 40 { 41 for(k=min(c,j/b);k>=1;k--) 42 { 43 ans[j]=max(ans[j],ans[j-k*b]+k*a); 44 } 45 } 46 } 47 } 48 else if(idx==3) 49 { 50 scanf("%lld%lld",&a,&b); 51 if(b==0) exit(-1); 52 else 53 { 54 for(j=b;j<=m;j++) 55 { 56 ans[j]=max(ans[j],ans[j-b]+a); 57 } 58 } 59 } 60 //for(int i=0;i<=m;i++) printf("a%lld %lld ",i,ans[i]); 61 } 62 for(i=1;i<=m;i++) ans[i]=max(ans[i],ans[i-1]); 63 an2=ans[m]; 64 for(i=0;i<dd.size();i++) 65 { 66 for(j=0;j<=m;j++) 67 { 68 an2=max(an2,ans[m-j]+dd[i].fi*j*j-dd[i].se*j); 69 } 70 } 71 printf("%lld",an2); 72 return 0; 73 }