sicily 1346. 金明的预算方案

 
  
//NOIP2006的题目,在转移的时候主件有四种转移方法:不加附件,加两附件,加附件一或加附件二
#include<iostream> //分组背包问题
#include<cstring>
using namespace std;
struct node
{
int v,w;
}table[
62][10];
int n,m,v[62],p[62],q[62],len[62],dp[40000];
int main()
{
while(cin>>n>>m)
{
for(int i=1;i<=m;++i)
{
cin
>>v[i]>>p[i]>>q[i];
if(q[i]==0)
{
len[i]
=1;
table[i][
0].v=v[i];table[i][0].w=p[i]*v[i]; //单独主件,不加附件
}
else
len[i]
=0; //表明是附件
}
for(int i=1;i<=m;++i)
if(q[i]>0)
{
if(len[q[i]]==1) //当前主件内没有附件
{
table[q[i]][
1].v=table[q[i]][0].v+v[i]; //主件加附件一
table[q[i]][1].w=table[q[i]][0].w+v[i]*p[i];
len[q[i]]
=2;
}
else //当前主件内已有附件一
{
table[q[i]][
2].v=table[q[i]][0].v+v[i]; //主件加附件二
table[q[i]][2].w=table[q[i]][0].w+v[i]*p[i];

table[q[i]][
3].v=table[q[i]][1].v+v[i]; //主件加附件一和二
table[q[i]][3].w=table[q[i]][1].w+v[i]*p[i];
len[q[i]]
=4;
}
}
memset(dp,
0,sizeof(dp));
for(int i=1;i<=m;++i)
if(q[i]==0) //如果该物品是附件则跳过
{
for(int j=n;j>=table[i][0].v;--j) //table[i][0].v在(table[i][0].v-table[i][len[i]-1].v)中肯定是最小的
for(int k=0;k<len[i];++k)
if(j>=table[i][k].v)
{
dp[j]
=max(dp[j],dp[j-table[i][k].v]+table[i][k].w);
}
}
cout
<<dp[n]<<endl;
}
return 0;
}

转载于:https://www.cnblogs.com/mjc467621163/archive/2011/07/06/2099617.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值