hdu3033 I love sneakers! 分组背包变形
August 11, 2013
Hdu
DP
分组背包要求每一组里面只能选一个,这个题目要求每一组里面至少选一个物品。 dp[i, j] 表示前 i 组里面在每组至少放进一个物品的情况下,当花费 j 的时候,所得到的的最大价值。这个状态可以由三个状态转移过来: a[i, j].b表示第 i 组第 j 个物品的花费,v表示背包容量。 初始化: 如果一种物品都不放,那么对应的所有的背包容量都是0,也就是:dp[0, 0~M] = 0; 其他的情况,都初始化成-INF。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <queue>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <vector>
#include <utility>
#include <functional>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <numeric>
#include <cassert>
#include <ctime>
#include <iterator>
const int INF = 0x3f3f3f3f;
const int dir[8][2] = {{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1}};
using namespace std;
typedef struct node
{
int b,v;
}node;
vector<node> a[11];
int dp[11][10009];
int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
int n, V, k;
while (~scanf("%d%d%d",&n,&V,&k))
{
for (int i=0;i<k;++i) a[i+1].clear();
int id; node t;
for (int i=0;i<n;++i)
{
scanf("%d",&id); scanf("%d%d",&t.b,&t.v); a[id].push_back(t);
}
bool flag=false;
for (int i=0;i<k;++i) if(a[i+1].size()==0) {printf("Impossible\n"); flag=true; break; }
if(flag) {continue;}
memset(dp,-INF,sizeof(dp));
for (int i=0;i<=V;++i) dp[0][i]=0;
for (int i=1;i<=k;++i)
{
for (int j=0;j<a[i].size();++j)
{
for (int v=V; v>=a[i][j].b;--v)
{
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);
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);
}
}
}
if(dp[k][V]==-INF) printf("Impossible\n");
else printf("%d\n",dp[k][V]);
}
return 0;
}
当然不是我自己想出来的…… 参考: 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