2017.8.8 魔兽地图DotR 思考记录

来源:互联网 发布:yy网络女主播不雅视频 编辑:程序博客网 时间:2024/04/29 14:56

   假题害人、、  明明说了是一棵树,却还要强行加一组坑爹数据   所以网上的题解挂了好多




  这题是很综合的树上背包问题、 由依赖关系转化为一些枚举来跑多重背包

  

  由于是 “一棵树” 所以放心根据高低级建边

  转移的时候除传统背包外 还需要多加一维 存往上进几个该装备用于合成

  父节点合并信息时用01背包,把每个儿子的花费细分  枚举装填合并时再把自己并入


  

  根据代码 会有疑问,就是再枚举儿子的时候会不会有需求没有被满足

  因为需求个数的儿子一定满足,g里所有满足的情况都是上一个物品满足的情况(if),,所以这样写是不会有问题的,不满足的情况没有被转移



码:

#include<iostream>#include<cstdio>#include<vector>#include<cstring> using namespace std;vector<int>xq1[60];vector<int>xq2[60];int n,m,sx[60],f[60][150][2017],g[2017],c[60],v[60],ans,i,j,t,x,y,f2[2017];char ch;bool si[60],woc;void dp(int o){int i,j,k,l;if(xq1[o].size()==0){  sx[o]=min(sx[o],m/c[o]);for(i=0;i<=sx[o];i++)    for(j=i;j<=sx[o];j++)f[o][i][j*c[o]]=(j-i)*v[o];return;}sx[o]=9999999;for(i=0;i<xq1[o].size();i++){dp(xq1[o][i]);sx[o]=min(sx[o],sx[xq1[o][i]]/xq2[o][i]);   // g[o]+=xq2[o][i]*c[xq1[o][i]];}for(i=0;i<=sx[o];i++)f[o][i][0]=0;for(i=0;i<xq1[o].size();i++)for(j=0;j<=sx[o];j++){for(k=0;k<=m;k++)g[k]=f[o][j][k];for(k=0;k<=m;k++)f[o][j][k]=-1;for(k=m;k>=0;k--)for(l=k;l>=0;l--){if(g[k-l]!=-1&&f[xq1[o][i]][j*xq2[o][i]][l]!=-1)f[o][j][k]=max(f[o][j][k],g[k-l]+f[xq1[o][i]][j*xq2[o][i]][l]),ans=max(ans,f[o][j][k]);}    }    for(i=0;i<=sx[o];i++)    for(j=i;j<=sx[o];j++)    for(k=0;k<=m;k++)    {    if(f[o][j][k]!=-1)f[o][i][k]=max(f[o][i][k],f[o][j][k]+(j-i)*v[o]),ans=max(ans,f[o][i][k]);}}int main(){scanf("%d%d",&n,&m);for(i=1;i<=n;i++){scanf("%d",&v[i]);scanf("%c",&ch);while(ch==' ')scanf("%c",&ch);if(ch=='A'){woc=1;scanf("%d",&t);while(t--){scanf("%d%d",&x,&y);xq1[i].push_back(x);xq2[i].push_back(y);si[x]=1;}}else{scanf("%d%d",&x,&y);c[i]=x;sx[i]=y;}}memset(f,-1,sizeof(f)); if(woc==0){   memset(f2,-1,sizeof(f2)); f2[0]=0;for(i=1;i<=n;i++)for(j=1;j<=sx[i];j++)for(int k=m;k>=c[i];k--){if(f2[k-c[i]]!=-1)f2[k]=max(f2[k],f2[k-c[i]]+v[i]),ans=max(ans,f2[k]);}printf("%d",ans);return 0;}for(int i=1;i<=n;i++)if(!si[i])dp(i);printf("%d",ans);}









原创粉丝点击