NOI2006:金明的预算方案
2012-04-06 15:18
239 查看
题目链接:http://www.rqnoj.cn/Status_Show.asp?SID=744089
这题纠结了两三天,主要是主件与附件之间的关系,然后选择问题让人纠结。我们可以将主件与对应的附件进行分组,对每个分组,我们有如下几种选择方式,都不选,只选主件,选主件与一个附件,选主件与多个附件,根据题意,每个分组最多有四种情况,这里可以直接枚举,这几种选择是互不相容的,这样就转化为了分组背包问题。那么接下来编程就相对容易的多了。
分组背包的动规方程:f(k ,v) = max{ f(k-1 ,v) , f(k-1 , v -c[i]) + w[i] , 物品i属于组k} ,其中f(k ,v)表示背包容量为v,从前k中选择若干件物品获得最大值。其实这个题目直接是有依赖的背包问题,一般先转化成对应的组,变成分组背包问题,对于每个组可以进行一次01背包问题。
代码如下:
这题纠结了两三天,主要是主件与附件之间的关系,然后选择问题让人纠结。我们可以将主件与对应的附件进行分组,对每个分组,我们有如下几种选择方式,都不选,只选主件,选主件与一个附件,选主件与多个附件,根据题意,每个分组最多有四种情况,这里可以直接枚举,这几种选择是互不相容的,这样就转化为了分组背包问题。那么接下来编程就相对容易的多了。
分组背包的动规方程:f(k ,v) = max{ f(k-1 ,v) , f(k-1 , v -c[i]) + w[i] , 物品i属于组k} ,其中f(k ,v)表示背包容量为v,从前k中选择若干件物品获得最大值。其实这个题目直接是有依赖的背包问题,一般先转化成对应的组,变成分组背包问题,对于每个组可以进行一次01背包问题。
代码如下:
#include <iostream> #include <string.h> #include <stdio.h> #include <deque> #include <stdlib.h> using namespace std ; const int maxn = 3205 ; struct Node { int p ; int c ; int w ; int in ; }; int dp[65][maxn] ; deque<Node> v1[65]; Node pack_node[65][65] ; int m ; int n ; int num ; void input(); void work() ; void init() ; int main() { work() ; return 0 ; } void work() { int i ; int v ; int k ; for(i = 0 ; i < 65 ; i ++) v1[i].clear() ; memset(dp , 0 , sizeof(dp)) ; memset(pack_node , 0 ,sizeof(pack_node)) ; //freopen("data.in" , "r" , stdin) ; input() ; init() ; for(i = 1 ; i <= num ; i ++) { for( v = m ; v >= 0 ; v--) { dp[i][v] = dp[i-1][v] ; for(k = 0 ; v >= pack_node[i][k].c && k < 4 ; k ++) { if(dp[i][v] < dp[i-1][v - pack_node[i][k].c] + pack_node[i][k].w) { dp[i][v] = dp[i-1][v - pack_node[i][k].c] + pack_node[i][k].w ; } } } } printf("%d\n" , dp[num][m] * 10) ; } void input() { int i ; int j ; Node a ; scanf("%d%d" , &m , &n) ; m = m / 10 ; num = 0 ; for(i = 1 ; i <= n ; i ++) { scanf("%d%d%d" ,&a.c , &a.w , &a.p ) ; a.in = i ; a.c = a.c / 10 ; if(a.p==0) v1[++num].push_front(a) ; else { for( j = 1 ; j <=num ; j ++) if(v1[j][0].in == a.p) break ; v1[j].push_back(a) ; } } } void init() { int i ; int len ; for(i = 1 ; i <= num ; i ++) { len = v1[i].size() ; if(len>=1) { pack_node[i][0].c = v1[i][0].c ; pack_node[i][0].w = v1[i][0].c * v1[i][0].w ; } if(len>=2) { pack_node[i][1].c = pack_node[i][0].c + v1[i][1].c ; pack_node[i][1].w = pack_node[i][0].w + v1[i][1].c * v1[i][1].w ; } if(len==3) { pack_node[i][2].c = pack_node[i][0].c + v1[i][2].c ; pack_node[i][2].w = pack_node[i][0].w + v1[i][2].c * v1[i][2].w ; pack_node[i][3].c = pack_node[i][1].c + v1[i][2].c ; pack_node[i][3].w = pack_node[i][1].w + v1[i][2].c * v1[i][2].w ; } } }
相关文章推荐
- NOIP 2006 tg T2金明的预算方案
- NOIP2006 金明的预算方案
- NOIP2006金明的预算方案
- 【NOIP2006】金明的预算方案
- 洛谷 1064 [NOIP2006] 金明的预算方案 背包DP
- NOIP提高组2006 金明的预算方案
- noip 2006 金明的预算方案
- [NOIP2006] 提高组 洛谷P1064 金明的预算方案
- ACM 背包DP [NOIP2006]金明的预算方案(budget)
- 【动态规划】Vijos P1313 金明的预算方案(NOIP2006提高组第二题)
- NOIP 2006 金明的预算方案(带条件的01背包)
- NOIP2006 金明的预算方案
- ACM 117. [NOIP2006] 金明的预算方案(dp+01背包变形)
- NOIP 2006 金明的预算方案
- NOIP 2006 提高组 复赛 budget 金明的预算方案
- noip2006 金明的预算方案
- 【wikioi1155】金明的预算方案(noip2006, 9018p1210, tyvj1057)
- NOIP 2006 金明的预算方案 (裸?)分组背包
- 依赖背包dp NOIP2006 vijos 1313 金明的预算方案
- SDNU 1179.金明的预算方案【NOIP 2006 提高组】【背包问题】【7月30】