zoukankan      html  css  js  c++  java
  • [NOIP2006]金明的预算方案

    嘟嘟嘟

    这虽然是一道水题,然而我Debug了快一个点儿,于是决定在A了之后发篇博客。

    这显然是一个有依赖性的背包问题,但是因为这道题一个主件最多只有两个附件,所以只有4种情况:

    1.只选主件

    2.主件+附件1

    3.主件+附件2

    4.主件+附件1+附件2

    (5.都不选)

    而且这四种情况是互斥的,那么这就相当于分组背包中的一个组,把原始的物品拆成上述新的物品(组合)后,跑正常的分组背包就行。

    题解里面开了个vector记录了每一个组(代码巨丑)。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<cctype>
     7 #include<cstdlib>
     8 #include<queue>
     9 #include<stack>
    10 #include<vector>
    11 using namespace std;
    12 #define enter puts("")
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 #define pr pair<int, int>
    17 #define mp make_pair
    18 typedef long long ll;
    19 typedef double db;
    20 const db eps = 1e-8;
    21 const int INF = 0x3f3f3f3f;
    22 const int maxm = 65;
    23 const int maxn = 32005;
    24 inline ll read()
    25 {
    26     ll ans = 0;
    27     char ch = getchar(), las = ' ';
    28     while(!isdigit(ch)) las = ch, ch = getchar();
    29     while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    30     if(las == '-') ans = -ans;
    31     return ans;
    32 }
    33 inline void write(ll x)
    34 {
    35     if(x < 0) putchar('-'), x = -x;
    36     if(x >= 10) write(x / 10);
    37     putchar(x % 10 + '0');
    38 }
    39 
    40 int m,n;
    41 vector<int> item[maxm];
    42 struct Node
    43 {
    44     int v, p, q;
    45 }e[maxm];
    46 
    47 vector<pr> v[maxm];
    48 int cnt = 0;
    49 ll dp[maxm][maxn];
    50 
    51 int main()
    52 {
    53     n = read(); m = read();
    54     for(int i = 1; i <= m; ++i)
    55     {
    56         e[i].v = read(); e[i].p = read(); e[i].q = read();
    57         if(e[i].q) item[e[i].q].push_back(i);
    58     }
    59     for(int i = 1; i <= m; ++i)
    60     {
    61         if(item[i].size())
    62         {
    63             v[++cnt].push_back(mp(e[i].v, e[i].v * e[i].p));
    64             v[cnt].push_back(mp(e[i].v + e[item[i][0]].v, e[i].v * e[i].p + e[item[i][0]].v * e[item[i][0]].p));
    65             if(item[i].size() == 2)
    66             {
    67                 v[cnt].push_back(mp(e[i].v + e[item[i][1]].v, e[i].v * e[i].p + e[item[i][1]].v * e[item[i][1]].p));
    68                 v[cnt].push_back(mp(e[i].v + e[item[i][0]].v + e[item[i][1]].v, e[i].v * e[i].p + e[item[i][0]].v * e[item[i][0]].p + e[item[i][1]].v * e[item[i][1]].p));
    69             }
    70         }
    71         else if(!e[i].q) v[++cnt].push_back(mp(e[i].v, e[i].v * e[i].p));
    72     }
    73     for(int k = 1; k <= cnt; ++k)
    74         for(int i = 0; i < (int)v[k].size(); ++i)
    75             for(int j = n; j >= 0; --j)
    76             {
    77                 dp[k][j] = max(dp[k][j], dp[k - 1][j]);
    78                 if(j - v[k][i].first >= 0) dp[k][j] = max(dp[k][j], dp[k - 1][j - v[k][i].first] + v[k][i].second);
    79     write(dp[cnt][n]), enter;
    80     return 0;
    81 }
    View Code

    题解到此结束,下面是我debug过程:

    1.快速的写完且过了样例后,交上去只有20,然后发现写成了01背包。

    2.开始改成分组背包,因为组数的序号问题出现了空的组,debug了10多分钟。

    3.最后改完后还是gg,下载的样例过不去,陷入无穷的debug过程。

    4.终于发现竟然是分组背包写错了,原来01背包偷懒的写法for(int j = m; i >= c[i]; --j)在分组背包里是错的,这样会导致一些好的状态没有继承,所以还是乖乖从m枚举到0吧……

  • 相关阅读:
    Spring配置事务中的 transactionAttributes 各属性含义及XML配置
    91. ExtJS获取父子、兄弟容器元素方法
    90.商城登录页面Extjs
    89. Ext.Button 按钮
    88. [ExtJS2.1教程-5]ToolBar(工具栏)
    87.Ext_菜单组件_Ext.menu.Menu
    86. Ext文本输入框:Ext.form.TextField属性汇总
    85.Ext.Window
    C 一个字符串有三段,第一段原样输出,第二段为要输出字符串的长度,第三段为依据第二段长度补齐第一段
    Spring in action(Spring实战) 第四版中文翻译
  • 原文地址:https://www.cnblogs.com/mrclr/p/9884681.html
Copyright © 2011-2022 走看看