P1064 [NOIP2006 提高组] 金明的预算方案
题解
遍历主件,和还剩下多少钱的情况下,最多有五种购买决策
1.不买
2.买主件
3.买主件+附件1
4.买主件+附件2
5.买主件+附件1+附件2
如果当前的钱够买,那就买买看,然后加上剩下的钱能买的最大值
code
#include<bits/stdc++.h>
using namespace std;
struct unit
{
int v,p,to,id;
}stuff[65];
vector<unit> G[65];
int len=0;
bool cmp(unit a,unit b)
{
return a.to<b.to;
}
int yinshe[65]={0};
int main()
{
int n,m;
cin>>n>>m;
n/=10;
for(int i=1;i<=m;i++)
{
cin>>stuff[i].v>>stuff[i].p>>stuff[i].to;
stuff[i].v/=10;
stuff[i].id=i;
}
sort(stuff+1,stuff+1+m,cmp);
for(int i=1;i<=m;i++)
{
int to=stuff[i].to;
if(!to)
{
G[++len].push_back({stuff[i].v,stuff[i].p,to,stuff[i].id});
yinshe[stuff[i].id]=len;
}
else G[yinshe[to]].push_back({stuff[i].v,stuff[i].p,to,stuff[i].id});
}
int dp[3205]={0};
for(int i=1;i<=len;i++)
{
int v0=G[i][0].v,p0=G[i][0].p;
for(int j=n;j>=v0;j--)
{
dp[j]=max(dp[j],dp[j-v0]+v0*p0);
if(G[i].size()>1)
{
int v1=G[i][1].v,p1=G[i][1].p;
if(j>=v1+v0) dp[j]=max(dp[j],dp[j-v0-v1]+v0*p0+v1*p1);
if(G[i].size()>2)
{
int v2=G[i][2].v,p2=G[i][2].p;
if(j>=v2+v0) dp[j]=max(dp[j],dp[j-v0-v2]+v0*p0+v2*p2);
if(j>=v2+v1+v0) dp[j]=max(dp[j],dp[j-v0-v1-v2]+v0*p0+v1*p1+v2*p2);
}
}
}
}
cout<<dp[n]<<'0';
return 0;
}

浙公网安备 33010602011771号