jzoj100044

版权声明:本博客為本人嘔心瀝血之作,未經允許禁止轉載! https://blog.csdn.net/qq_39529862/article/details/85017405

完全背包問題
我們可以將數組內每個元素看成一個物品,這樣問題就轉化成:
現有n個物品,每個物品可以取a[i]~b[i]個,價值為d[i],費用為c[i],問怎麼樣取讓費用為0且價值最大
我們可以先每種物品取a[i]個,這樣每個物品變成了可取0~b[i]-a[i]個
記之前c總和為va,則現在我們要取-va才能使總和為0
多重背包即可,要加二進制優化

#include<bits/stdc++.h>
using namespace std;
#define N 2000010
int a[N],b[N],c[N],d[N],n,ans,p[N],va,ct,f[N],v[N];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
		ans+=a[i]*d[i];
		va+=a[i]*c[i];
		int rrr=b[i]-a[i];
		for(int j=1;j<=rrr;j*=2){
			rrr-=j;
			p[++ct]=c[i]*j;
			v[ct]=d[i]*j;
		}
		if(rrr)p[++ct]=(rrr)*c[i];
		if(rrr)v[ct]=(rrr)*d[i];
	}
	va=-va;
	memset(f,-63,sizeof(f));
	f[0]=0;
	for(int i=1;i<=ct;i++)
		for(int j=va;j>=p[i];j--)
			f[j]=max(f[j],f[j-p[i]]+v[i]);
	printf("%d",ans+f[va]);
}

猜你喜欢

转载自blog.csdn.net/qq_39529862/article/details/85017405