P1899 魔法物品


非常好的一道dp题目!!!!

首先对于普通物品和b-a<=p的魔法物品 直接用a值卖掉就好

卖完之后我们手头有val的钱

分两种情况:

1.假如此时val>=p

那么剩下的魔法物品都可以卖了,因为保证买完一个魔法物品钱一定任大于p

2.假如此时val

我们就要先卖魔法物品的a值(因为不够买卷轴),等到凑够p以后,问题就又回到1了

现在关键就是怎么凑到p才能使得最后结果最大

设dp[i]表示凑到i的时候 损失最小为多少

点击查看代码
#include
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<>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<=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<