其他分享
首页 > 其他分享> > P1899 魔法物品

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