• 洛谷 P1064 金明的预算方案


    先把主件拆开。例如两个附件的物品,拆成只买主件、主+附1、主+附2、主+附1+附2这四种对于这个物品的选法。

    然后跑类似普通背包的,ans[i][j]表示前i个物品用j的钱的最大收益。如果当前物品为附件则ans[i]直接从ans[i-1]复制,直接忽略当前物品。否则枚举当前物品的所有选法,ans[i][j]=max(ans[i-1][j],ans[i-1][j-v[i]]+val[i])更新。此处v[i]表示当前枚举到的对于当前物品的选法的总费用,val[i]表示当前枚举到的对于当前物品的选法的总价值。

    错误记录(调至少半小时):

    1.在当前物品为附件时,直接跳掉了,没有复制ans[i-1]的答案

    2.在拆开物品的时候,某一行的v2[i]的push_back的元素中却出现了cost[...]

    3.57行直接max(ans[i-1][k],ans[i-1][k-c2[i][j]]+v2[i][j]),把前面选法得到的好的答案丢了

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<vector>
     4 using namespace std;
     5 int cost[70],val[70],q[70];
     6 vector<int> c2[70],v2[70],s[70];
     7 int ans[62][32100];
     8 int n,m;
     9 int main()
    10 {
    11     int i,sz,j,k;
    12     scanf("%d%d",&n,&m);
    13     for(i=1;i<=m;i++)
    14     {
    15         scanf("%d%d%d",&cost[i],&val[i],&q[i]);
    16         val[i]=val[i]*cost[i];
    17         if(q[i]!=0)    s[q[i]].push_back(i);
    18     }
    19     for(i=1;i<=m;i++)
    20         if(q[i]==0)
    21         {
    22             sz=s[i].size();
    23             if(sz==0)
    24             {
    25                 c2[i].push_back(cost[i]);
    26                 v2[i].push_back(val[i]);
    27             }
    28             else if(sz==1)
    29             {
    30                 c2[i].push_back(cost[i]);
    31                 v2[i].push_back(val[i]);
    32                 c2[i].push_back(cost[i]+cost[s[i][0]]);
    33                 v2[i].push_back(val[i]+val[s[i][0]]);
    34             }
    35             else if(sz==2)
    36             {
    37                 c2[i].push_back(cost[i]);
    38                 v2[i].push_back(val[i]);
    39                 c2[i].push_back(cost[i]+cost[s[i][0]]);
    40                 v2[i].push_back(val[i]+val[s[i][0]]);
    41                 c2[i].push_back(cost[i]+cost[s[i][1]]);
    42                 v2[i].push_back(val[i]+val[s[i][1]]);
    43                 c2[i].push_back(cost[i]+cost[s[i][0]]+cost[s[i][1]]);
    44                 v2[i].push_back(val[i]+val[s[i][0]]+val[s[i][1]]);
    45             }
    46         }
    47 //    for(i=1;i<=m;i++)
    48 //    {
    49 //        for(int j=0;j<c2[i].size();j++)    printf("%d %d ",c2[i][j],v2[i][j]);
    50 //        puts("");
    51 //    }
    52     for(i=1;i<=m;i++)
    53     {
    54         for(j=0;j<c2[i].size();j++)
    55         {
    56             for(k=c2[i][j];k<=n;k++)
    57                 ans[i][k]=max(ans[i][k],max(ans[i-1][k],ans[i-1][k-c2[i][j]]+v2[i][j]));
    58         }
    59         for(k=0;k<=n;k++)
    60             ans[i][k]=max(ans[i][k],ans[i-1][k]);
    61     }
    62     printf("%d",*max_element(ans[m]+1,ans[m]+n+1));
    63     return 0;
    64 }
  • 相关阅读:
    2019-9-23-dotnet-判断特定进程存在方法
    2019-7-4-win10-uwp-处理用户点击关闭按钮
    2019-7-4-win10-uwp-处理用户点击关闭按钮
    2019-9-2-如何使用本模板搭建博客
    2019-8-31-dotnet-使用-System.CommandLine-写命令行程序
    2018-11-3-WPF-内部的5个窗口之-MediaContextNotificationWindow
    2019-4-7-VisualStudio-解决方案筛选器-slnf-文件
    2019-9-2-用自动机的思想说明光速
    2019-10-26-dotnet-core-发布只有一个-exe-的方法
    2018-2-13-win10-uwp-获取按钮鼠标左键按下
  • 原文地址:https://www.cnblogs.com/hehe54321/p/7804247.html
Copyright © 2020-2023  润新知