求教各位大佬

P1064 [NOIP2006 提高组] 金明的预算方案

```c #include<cstdio> #include<iostream> using namespace std; int n,m,v[65],p[65],q[65],a[65][4],opt[32005],arr[65]; int main() { int i,j,c; scanf("%d %d", &n,&m); for(i=1;i<=m;i++) { scanf("%d %d %d",&v[i],&p[i],&q[i]); arr[i]=v[i]*p[i]; if(q[i]!=0) { a[q[i]][1]++; for(j=2;j<=4;j++) { if(a[q[i]][j]==0) {a[q[i]][j]=i;break;} } } } for(i=1;i<=m;i++) for(j=n;j>=1;j--) if(q[i]==0) { opt[j]=max(opt[j],opt[j-v[i]]+arr[i]); for(c=2;c<=(a[i][1]+1);c++) {opt[j]=max(opt[j],opt[j-v[a[i][c]]]+(v[a[i][c]]*p[a[i][c]]));} } printf("%d ",opt[n]); return 0; } ```
by Citus_Neru_index @ 2019-06-25 20:56:01


@[Accelerator_zhang](/space/show?uid=93356) 本蒟蒻~~看不出错但~~可以提供代码 ``` #include <iostream> using namespace std; int const N=32001,M=61; int n,m,t,k,f[N],w[M][3],v[M],p[M],q[M],x[M]; int main(){ cin>>n>>m;// for (int i=1;i<=m;i++){ cin>>v[i]>>p[i]>>q[i]; if (q[i]==0) x[++t]=i;//保存主件的物品序号 else w[q[i]][++w[q[i]][0]]=i;//保存附件, w[k][0]表示附件个数,w[k][1]表示附件1序号,w[k][2]表示附件2序号 } for (int i=1;i<=t;i++) {//主件个数循环 k=x[i];//主件物品序号 for (int j=n;j>=0;j--){//总钱数 if (j>=v[k]) f[j]=max(f[j],f[j-v[k]]+v[k]*p[k]);//主件判断 if ((w[k][0]>=1) && (j>=(v[k]+v[w[k][1]])))//存在满足条件附件 f[j]=max(f[j],f[j-v[k]-v[w[k][1]]] + v[k]*p[k] + v[w[k][1]]*p[w[k][1]]); if ((w[k][0]>=2) && (j>=(v[k]+v[w[k][2]]))) f[j]=max(f[j],f[j-v[k]-v[w[k][2]]]+v[k]*p[k]+v[w[k][2]]*p[w[k][2]]); if ((w[k][0]>=2) && (j>=(v[k]+v[w[k][1]]+v[w[k][2]]))) f[j]=max(f[j],f[j-v[k]-v[w[k][1]]-v[w[k][2]]]+v[k]*p[k]+v[w[k][1]]*p[w[k][1]]+v[w[k][2]]*p[w[k][2]]); } } cout<<f[n]<<endl; return 0; } ```
by fzhfzh @ 2019-06-25 21:01:16


希望更丰富的展现?使用Markdown
by ferrum_cccp @ 2019-06-25 21:01:25


这题想当年我也调了好久……再给一坨代码 ```cpp #include<cstdio> int n,m,v[66],p[66],q[66],f[66][32222]={0}; int a[66][66],b[66]={0},w[32222]={0}; int main() { scanf("%d%d",&n,&m); n=n/10; for(int i=1;i<=m;i++) b[i]=1; for(int i=1;i<=m;i++) { scanf("%d%d%d",&v[i],&p[i],&q[i]); v[i]/=10; p[i]*=v[i]; if(q[i]==0) a[i][1]=i; else a[q[i]][++b[q[i]]]=i; } for(int i=1;i<=m;i++) { for(int j=2;j<=b[i];j++) { for(int k=n-v[a[i][1]];k>=v[a[i][j]];k--) if(f[i][k-v[a[i][j]]]+p[a[i][j]]>f[i][k]) f[i][k]=f[i][k-v[a[i][j]]]+p[a[i][j]]; } for(int j=n-v[a[i][1]];j>=0;j--) { f[i][j+v[a[i][1]]]=f[i][j]+p[a[i][1]]; } for(int j=0;j<v[a[i][1]];j++) f[i][j]=0; } for(int i=1;i<=m;i++) for(int j=n;j>=0;j--) for(int k=1;k<=j;k++) if(w[j]<w[j-k]+f[i][k]) w[j]=w[j-k]+f[i][k]; printf("%d",w[n]*10); return 0; } ```
by guoxinyugz @ 2019-06-25 21:07:11


这道题有个坑,就是每行输出第三个数,表示主附件的,和属于第几个主件的,指的是第几行的东西
by zimindaada @ 2019-06-25 21:18:39


@[zimindaada](/space/show?uid=134635) 可能是这个坑,我没仔细看
by zimindaada @ 2019-06-25 21:18:52


我也调了好久,~~最终在题解的帮助下A了~~ 给你一坨代码 ```c++ #include<bits/stdc++.h> using namespace std; int N,M; int zjw[200],zjp[200],fjw[200][10],fjp[200][10],f[32001]; int main(){ scanf("%d%d",&N,&M); for(int i=1;i<=M;i++){ int v,p,q; scanf("%d%d%d",&v,&p,&q); if(q==0){ zjw[i]=v; zjp[i]=v*p; } else{ fjw[q][0]++; fjw[q][fjw[q][0]]=v; fjp[q][fjw[q][0]]=v*p; } } for(int i=1;i<=M;i++){ for(int j=N;zjw[i]!=0 && j>=zjw[i];j--){ f[j]=max(f[j],f[j-zjw[i]]+zjp[i]); if(j>=zjw[i]+fjw[i][1]) f[j]=max(f[j],f[j-zjw[i]-fjw[i][1]]+zjp[i]+fjp[i][1]); if(j>=zjw[i]+fjw[i][2]) f[j]=max(f[j],f[j-zjw[i]-fjw[i][2]]+zjp[i]+fjp[i][2]); if(j>=zjw[i]+fjw[i][1]+fjw[i][2]) f[j]=max(f[j],f[j-zjw[i]-fjw[i][1]-fjw[i][2]]+zjp[i]+fjp[i][1]+fjp[i][2]); } } printf("%d\n",f[N]); return 0; } ```
by _lcy_ @ 2019-06-25 21:21:57


谢谢各位了
by Citus_Neru_index @ 2019-06-27 20:56:45


|