zoukankan      html  css  js  c++  java
  • hdu3033 I love sneakers! 分组背包变形

    分组背包要求每一组里面只能选一个,这个题目要求每一组里面至少选一个物品。

    dp[i, j] 表示前 i 组里面在每组至少放进一个物品的情况下,当花费 j 的时候,所得到的的最大价值。这个状态可以由三个状态转移过来:

    1. dp[i-1, v-a[i,j].b] 表示第 i 组没有放过,将要放进第 i 组里面的第 j 个物品
    2. dp[i, v-a[i,j].b] 表示第 i 组已经放过了,将要放进第 i 组里面的第 j 个物品
    3. dp[i, j] 表示第 i 中已经放过了,不放第 i 组里面的第 j 个物品

    a[i, j].b表示第 i 组第 j 个物品的花费,v表示背包容量。

    初始化:

    如果一种物品都不放,那么对应的所有的背包容量都是0,也就是:dp[0, 0~M] = 0;

    其他的情况,都初始化成-INF。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cmath>
     6 #include <cctype>
     7 #include <algorithm>
     8 #include <queue>
     9 #include <deque>
    10 #include <queue>
    11 #include <list>
    12 #include <map>
    13 #include <set>
    14 #include <vector>
    15 #include <utility>
    16 #include <functional>
    17 #include <fstream>
    18 #include <iomanip>
    19 #include <sstream>
    20 #include <numeric>
    21 #include <cassert>
    22 #include <ctime>
    23 #include <iterator>
    24 const int INF = 0x3f3f3f3f;
    25 const int dir[8][2] = {{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1}};
    26 using namespace std;
    27 typedef struct node
    28 {
    29     int b,v;
    30 }node;
    31 vector<node> a[11];
    32 int dp[11][10009];
    33 int main(void)
    34 {
    35     #ifndef ONLINE_JUDGE
    36     freopen("in.txt","r",stdin);
    37     #endif // ONLINE_JUDGE
    38     int n, V, k;
    39     while (~scanf("%d%d%d",&n,&V,&k))
    40     {
    41         for (int i=0;i<k;++i) a[i+1].clear();
    42         int id; node t;
    43         for (int i=0;i<n;++i)
    44         {
    45             scanf("%d",&id); scanf("%d%d",&t.b,&t.v); a[id].push_back(t);
    46         }
    47         bool flag=false;
    48         for (int i=0;i<k;++i) if(a[i+1].size()==0) {printf("Impossible
    "); flag=true; break; }
    49         if(flag) {continue;}
    50         memset(dp,-INF,sizeof(dp));
    51         for (int i=0;i<=V;++i) dp[0][i]=0;
    52         for (int i=1;i<=k;++i)
    53         {
    54             for (int j=0;j<a[i].size();++j)
    55             {
    56                 for (int v=V; v>=a[i][j].b;--v)
    57                 {
    58                     if(dp[i][v-a[i][j].b]!=-INF) dp[i][v]=max(dp[i][v],dp[i][v-a[i][j].b]+a[i][j].v);
    59                     if(dp[i-1][v-a[i][j].b]!=INF) dp[i][v]=max(dp[i][v],dp[i-1][v-a[i][j].b]+a[i][j].v);
    60                 }
    61             }
    62         }
    63         if(dp[k][V]==-INF) printf("Impossible
    ");
    64         else printf("%d
    ",dp[k][V]);
    65     }
    66     return 0;
    67 }

    当然不是我自己想出来的……

    参考:

    http://www.cnblogs.com/zhourongqing/archive/2012/08/21/2649972.html

    http://www.docin.com/p-374335925.html

    http://www.cnblogs.com/nanke/archive/2011/11/24/2261695.html

  • 相关阅读:
    面向对象三大特性?
    final finally finalize区别?
    LeetCode122-买卖股票的最佳时机2(贪心算法)
    LeetCode119-杨辉三角2(题目有Bug,动态规划)
    九度OJ 1051:数字阶梯求和 (大数运算)
    九度OJ 1050:完数 (数字特性)
    九度OJ 1049:字符串去特定字符 (基础题)
    九度OJ 1048:判断三角形类型 (基础题)
    九度OJ 1047:素数判定 (素数)
    九度OJ 1046:求最大值 (基础题)
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3251735.html
Copyright © 2011-2022 走看看