• HDU3033I love sneakers!(分组背包)


    http://acm.hdu.edu.cn/showproblem.php?pid=3033

    本题的意思就是说现在有n种牌子的鞋子,每种品牌有一些不同的鞋,每双鞋子都有一个特定的权值,现在要求每种品牌的鞋子都至少收集一双,有一定量的钱,问获得的最大的权值是多少。

    这个题与普通的分组背包不同就在于每一组都至少选一个,(正好这个难道我了= =)

    网上找了解题报告,解题方法很巧妙,就是先将每一个DP值初始化为一个值,比如-1,表示所有的状态都不合法

    那么转移方程就是

                        if(DP[i][k-cost[i][j]] != -1)
                            DP[i][k] = max(DP[i][k], DP[i][k-cost[i][j]]+val[i][j]);
                        if(DP[i-1][k-cost[i][j]] != -1)
                            DP[i][k] = max(DP[i][k], DP[i-1][k-cost[i][j]]+val[i][j]);

    这样一来,如果要得到一个DP值,就必须从一个合法的状态得到,首先,如果DP[i][k-cost[i][j]]!=-1,那么说明这一层已经存放了物品,否则就是没有放那么就必须从上一层的状态转移得到。

    得解。

    见代码:

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <vector>
     8 #include <cstdio>
     9 #include <cctype>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 #define INF 0x3f3f3f3f
    16 #define MAX(a,b) (a > b ? a : b)
    17 #define MIN(a,b) (a < b ? a : b)
    18 #define lson k<<1, L, mid
    19 #define rson k<<1|1, mid+1, R
    20 #define mem0(a) memset(a,0,sizeof(a))
    21 
    22 typedef long long LL;
    23 const double eps = 1e-12;
    24 const int MAXN = 1005;
    25 const int MAXM = 5005;
    26 
    27 int num[11],cost[11][110], val[11][110];
    28 int DP[11][11000], sum;
    29 int N, M, K;
    30 
    31 void init()
    32 {
    33     mem0(DP); mem0(cost);mem0(val);mem0(num);
    34     num[0] = 1;
    35 }
    36 
    37 void ReadData()
    38 {
    39     int a, b, c;
    40     for(int i=0;i<N;i++)
    41     {
    42         scanf("%d%d%d", &a, &b, &c);
    43         cost[a][num[a]] = b;
    44         val[a][num[a]] = c;
    45         num[a]++;
    46     }
    47 }
    48 
    49 int main()
    50 {
    51     while(~scanf("%d %d %d", &N, &M, &K))
    52     {
    53         init();
    54         ReadData();
    55         for(int i=0;i<=K;i++)
    56         {
    57             for(int j=0;j<=M;j++)
    58             {
    59                 DP[i][j] = i==0?0:-1;
    60             }
    61         }
    62         for(int i=1;i<=K;i++)
    63         {
    64             for(int j=0;j<num[i];j++)
    65             {
    66                 for(int k=M;k>=cost[i][j];k--)
    67                 {
    68                     if(DP[i][k-cost[i][j]] != -1)
    69                         DP[i][k] = max(DP[i][k], DP[i][k-cost[i][j]]+val[i][j]);
    70                     if(DP[i-1][k-cost[i][j]] != -1)
    71                         DP[i][k] = max(DP[i][k], DP[i-1][k-cost[i][j]]+val[i][j]);
    72                 }
    73             }
    74         }
    75         if(DP[K][M]<0)printf("Impossible
    ");
    76         else printf("%d
    ",DP[K][M]);
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    JavaScript数据类型和变量学习小记
    如何在windows下安装Python的PIL库
    maoguy的第一条博客
    Ⅲ. 通过git管理github上托管的代码
    Ⅱ. Git的本地操作--下(不会使github远程仓库发生任何改变)
    Ⅰ. Git的本地操作--上(不会使github远程仓库发生任何改变)
    Linux下Vi/Vim编辑器使用案例(基于Ubuntu)
    Selenium+python上传本地文件或者图片
    Selenium+python操作id为动态变化的frame(iframe)
    Quick-cocos2d-x v3.3 SocketTCP链接(转)
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/3442611.html
Copyright © 2020-2023  润新知