hdu 2639 Bone Collector II

一拿到这题的时候,一时脑阻塞了,虽然知道肯定是01背包,但是却不知道怎么变形。

后来看了网上的代码,才恍然大悟,原来只需将01背包优化过程中的前K种情况储存起来就可以了。

01背包的状态转移方程为:dp[i][v]=max(dp[i-1][v],dp[i-1][v-vi[i]]+va[i]);而要储存起前K种情况就需要将状态方程转化为:dp[i-1][v]=>dp[i-1][v][1……k],dp[i-1][v-vi[i]]+va[i]=>dp[i-1][v-vi[i]][1……k]+va[i];

这样就可以解决该问题了。

这是AC代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int vi[105],va[105],dp[1005][35],a[35],b[35];
int main(void)
{
	int t;
	cin>>t;
	while(t--){
		int n,v,k;
		cin>>n>>v>>k;
		for(int i=0;i<n;i++)
			cin>>va[i];
		for(int i=0;i<n;i++)
			cin>>vi[i];
		memset(dp,0,sizeof(dp));
		for(int i=0;i<n;i++){
			for(int vo=v;vo>=vi[i];vo--){
				for(int kk=1;kk<=k;kk++){
					a[kk]=dp[vo-vi[i]][kk]+va[i];
					b[kk]=dp[vo][kk];
				}
				b[k+1]=a[k+1]=-1;
				int aa,bb,c;
				aa=bb=c=1;
				while(c<=k&&(a[aa]!=-1||b[bb]!=-1)){
					if(a[aa]>b[bb])
						dp[vo][c]=a[aa],aa++;
					else
						dp[vo][c]=b[bb],bb++;
					if(dp[vo][c]!=dp[vo][c-1])
						c++;
				}
			}
		}
		cout<<dp[v][k]<<endl;
	}
}



你可能感兴趣的:(hdu 2639 Bone Collector II)