P1899 魔法物品
作者:互联网
非常好的一道dp题目!!!!
首先对于普通物品和b-a<=p的魔法物品 直接用a值卖掉就好
卖完之后我们手头有val的钱
分两种情况:
1.假如此时val>=p
那么剩下的魔法物品都可以卖了,因为保证买完一个魔法物品钱一定任大于p
2.假如此时val<p
我们就要先卖魔法物品的a值(因为不够买卷轴),等到凑够p以后,问题就又回到1了
现在关键就是怎么凑到p才能使得最后结果最大
设dp[i]表示凑到i的时候 损失最小为多少
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
#define inf 1e9
const int maxn=5e3+5;
int dp[maxn<<1];
int cnt,n,P,val,maxx,tot,ans=1e9;
struct node{
int a,b,cha;
}v[maxn];
int main(){
string in;
cin>>n>>P;
getline(cin,in);//读取换行符 不能用getchar()
for(int i=1;i<=n;i++){
stringstream st;//黑科技
getline(cin,in);
int aa,bb;
st<<in;st>>aa;
if(st>>bb&&bb-aa>=P){
v[++cnt].a=aa;
v[cnt].b=bb;
v[cnt].cha=bb-aa-P;
maxx+=aa;
tot+=v[cnt].cha;
}else
val+=aa;
}
if(val>=P){
for(int i=1;i<=cnt;i++)
val+=(v[i].b-P);
cout<<val<<endl;
return 0;
}
for(int i=0;i<=val;i++)dp[i]=0;
for(int i=val+1;i<=val+maxx;i++)dp[i]=inf;
for(int i=1;i<=cnt;i++)
for(int j=val+maxx;j-v[i].a>=0;j--)
dp[j]=min(dp[j],dp[j-v[i].a]+v[i].cha);
for(int i=P;i<=val+maxx;i++)
ans=min(ans,dp[i]);
if(ans==inf){
cout<<val+maxx<<endl;
return 0;
}
cout<<tot+val+maxx-ans<<endl;
return 0;
}
标签:aa,cnt,P1899,bb,val,int,魔法,物品,dp 来源: https://www.cnblogs.com/wzxbeliever/p/16078395.html