http://www.vijos.cn/Problem_Show.asp?id=1313
#include<iostream> using namespace std; struct Node { int v;//该物品的价格 int p;//该物品的重要度 int mark;//标记该物品是否为主件,mark=0表示为主件,否则表示其主件号 int fj1;//附件1 * fj1 = 0 表示没有附件1,否则为附件号 int fj2;//附件2 * fj2 = 0 表示没有附件2,否则为附件号 }; int MAX(int x,int y) { if(x>y) return x; else return y; } int main() { int N,m;//N 钱数,m 物品数量 while(cin>>N>>m) { int i,j,temp,p1,p2; int dp[32001]; Node obj[60]; for(i=1;i<=m;i++) //开始都没有附件 obj[i].fj1 = obj[i].fj2 = 0;
for(i=1;i<=m;i++) { scanf("%d%d%d",&obj[i].v,&obj[i].p,&obj[i].mark); if(obj[i].mark != 0) //不是主件 就要找其主件 { if(obj[obj[i].mark].fj1 != 0) { if(obj[obj[obj[i].mark].fj1].v > obj[i].v)//保证附件1的价格要小 { temp = obj[obj[i].mark].fj1; obj[obj[i].mark].fj1 = i; obj[obj[i].mark].fj2 = temp; } else obj[obj[i].mark].fj2 = i; } else obj[obj[i].mark].fj1 = i; } } if(obj[1].mark == 0) { if(obj[1].fj1 == 0 && obj[1].fj2 == 0) { for(j=0;j<obj[1].v;j++) dp[j] = 0; for(;j<=N;j++) dp[j] = obj[1].v * obj[1].p; } else if(obj[1].fj1 != 0 && obj[1].fj2 == 0) { p1 = obj[1].fj1; for(j=0;j<obj[1].v;j++)//什么都不能买 dp[j] = 0; for(;j<obj[1].v + obj[p1].v ;j++)//只能买主件 dp[j] = obj[1].v * obj[1].p; for(;j<=N;j++) dp[j] = obj[1].v * obj[1].p + obj[p1].v * obj[p1].p; } else { p1 = obj[1].fj1; p2 = obj[1].fj2; for(j=0;j<obj[1].v;j++)//什么都不能买 dp[j] = 0;
for(;j<obj[1].v + obj[p1].v ;j++) //只能买主件 dp[j] = obj[1].v*obj[1].p;
for(;j<obj[1].v + obj[p2].v ;j++) //能买主件与附件1 dp[j] = obj[1].v*obj[1].p + obj[p1].v*obj[p1].p;
for(;j<obj[1].v + obj[p1].v + obj[p2].v ;j++) //能买主件与一个附件 dp[j] = MAX(obj[1].v*obj[1].p + obj[p1].v*obj[p1].p,obj[1].v*obj[1].p + obj[p2].v*obj[p2].p);
for(;j<=N;j++) //都能买 dp[j] = obj[1].v*obj[1].p + obj[p1].v*obj[p1].p + obj[p2].v*obj[p2].p; } }//if(obj[1].mark == 0) else //第1件物品是附件 { for(j=0;j<=N;j++) dp[j] = 0; } for(i=2;i<=m;i++) { if(obj[i].mark == 0)//第i件物品是主件 { if(obj[i].fj1 == 0 && obj[i].fj2 == 0) //没有附件 { //只够买主件 for(j=N;j>=obj[i].v;j--) dp[j] = MAX(dp[j],dp[j-obj[i].v] + obj[i].v*obj[i].p); } else if(obj[i].fj1 != 0 && obj[i].fj2 == 0) //有附件1 { p1 = obj[i].fj1; for(j=N;j>=obj[i].v + obj[p1].v;j--) { temp = dp[j]; //买主件与附件1 if(temp < dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p) temp = dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p; //只买主件 if(temp < dp[j-obj[i].v ] + obj[i].v*obj[i].p) temp = dp[j-obj[i].v ] + obj[i].v*obj[i].p; dp[j] =temp; } //只够买主件 for(;j>=obj[i].v;j--) dp[j] = MAX(dp[j],dp[j-obj[i].v] + obj[i].v*obj[i].p); } else //有两个附件 { p1 = obj[i].fj1; p2 = obj[i].fj2;
for(j=N;j>=obj[i].v + obj[p1].v + obj[p2].v;j--) { temp = dp[j]; //主件与两附件都买 if(temp < dp[j-obj[i].v-obj[p1].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p + obj[p2].v*obj[p2].p) temp = dp[j-obj[i].v-obj[p1].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p + obj[p2].v*obj[p2].p; //买主件与附件2 if(temp < dp[j-obj[i].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p2].v*obj[p2].p) temp = dp[j-obj[i].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p2].v*obj[p2].p; //买主件与附件1 if(temp < dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p) temp = dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p; //只买主件 if(temp < dp[j-obj[i].v ] + obj[i].v*obj[i].p) temp = dp[j-obj[i].v ] + obj[i].v*obj[i].p; dp[j] = temp; } for(;j>=obj[i].v + obj[p2].v;j--) { temp = dp[j]; //买主件与附件2 if(temp < dp[j-obj[i].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p2].v*obj[p2].p) temp = dp[j-obj[i].v-obj[p2].v] + obj[i].v*obj[i].p + obj[p2].v*obj[p2].p; //买主件与附件1 if(temp < dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p) temp = dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p; //只买主件 if(temp < dp[j-obj[i].v ] + obj[i].v*obj[i].p) temp = dp[j-obj[i].v ] + obj[i].v*obj[i].p; dp[j] = temp; } for(;j>=obj[i].v + obj[p1].v;j--) { temp = dp[j]; //买主件与附件1 if(temp < dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p) temp = dp[j-obj[i].v-obj[p1].v] + obj[i].v*obj[i].p + obj[p1].v*obj[p1].p; //只买主件 if(temp < dp[j-obj[i].v ] + obj[i].v*obj[i].p) temp = dp[j-obj[i].v ] + obj[i].v*obj[i].p; dp[j] = temp; } //只够买主件 for(;j>=obj[i].v;j--) dp[j] = MAX(dp[j],dp[j-obj[i].v] + obj[i].v*obj[i].p); } } } cout<<dp[N]<<endl; } return 0; }
/**//* 4500 12 100 3 0 400 5 0 300 5 0 1400 2 0 500 2 0 800 2 4 1400 5 4 300 5 0 1400 3 8 500 2 0 1800 4 0 440 5 10 1000 5 300 5 0 400 2 0 300 5 2 300 4 2 600 4 0 */
|
|
|
公告
导航
统计
- 随笔: 84
- 文章: 7
- 评论: 49
- 引用: 0
常用链接
留言簿(6)
随笔分类
随笔档案
文章分类
文章档案
相册
百事百通
搜索
积分与排名
最新评论
阅读排行榜
评论排行榜
|
|