解析Bone Collector II HDU - 2639

#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
int main()
{
	int T;
	cin>>T;
	int dp[maxn][33],val[maxn],vol[maxn],A[33],B[33];
	while(T--)
	{
		int n,v,k;
		cin>>n>>v>>k;
		int i,j,kk;
		for(i=0;i<n;i++)
            cin>>val[i];//价值
		for(i=0;i<n;i++)
            cin>>vol[i];//体积
		memset(dp,0,sizeof(dp));
		int a,b,c;
		for(i=0;i<n;i++)
            for(j=v;j>=vol[i];j--)//01背包循环
			{
				for(kk=1;kk<=k;kk++)//三个参数考虑所以循环三重
				{//因为是要求解K优解,所以用A[],B[]两个数组来替换max/min的作用,构成有序队列
				    //遍历每一个k优解进行考虑
					A[kk]=dp[j-vol[i]][kk]+val[i];//取得当前值
					B[kk]=dp[j][kk];//不取当前值
				}
				A[kk]=-1,B[kk]=-1;//kk=k+1所以可以防止越界
				a=b=c=1;
				while(c<=k&&(A[a]!=-1||B[b]!=-1))//反复更新前k优解
				{
					if(A[a]>B[b])
						dp[j][c]=A[a++];
					else
						dp[j][c]=B[b++];
					if(dp[j][c]!=dp[j][c-1])//这一轮中的不同大小的值
						c++;
				}
			}
		cout<<dp[v][k]<<endl;;
	}
	return 0;
}

©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页