Bone Collector II 背包

Bone Collector II
原题链接https://vjudge.net/contest/348156#problem/D
在这里插入图片描述
在这里插入图片描述
对于寻找第k个最大值的题,我们要添加一个维度记录为第几个值
将所有情况找出,然后进行一个一个往数组中排序添加,最后输出最大值。

#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
long long dp[1005][105];
int main()
{
	long long t;
	scanf("%lld",&t);
	while(t--)
	{
		long long n,v,k,sum1;
		long long i,j;
		long long a[10005];
		long long b[10005];
		scanf("%lld %lld %lld",&n,&v,&k);
		for(i=1; i<=n; i++)
		{
			scanf("%lld",&a[i]);
		}
		for(i=1; i<=n; i++)
		{
			scanf("%lld",&b[i]);
		}
		memset(dp,0,sizeof(dp));
		long long c[1005];
		long long d[1005];
		for(i=1; i<=n; i++)
		{
		//	printf("*\n");
			for(j=v; j>=b[i]; j--)
			{
				//printf("**\n");
				for(sum1=1; sum1<=k; sum1++)
				{
					c[sum1]=dp[j][sum1];//更新从1-k;的数据
					d[sum1]=dp[j-b[i]][sum1]+a[i];
				}
				c[k+1]=-1;
				d[k+1]=-1;
				sum1=1;
				long long x=1,y=1;
				while(sum1!=k+1&&(c[x]!=-1||d[y]!=-1))//结束条件,选取够k个数
				{
					if(c[x]>d[y])//更新第k个数,选最大的
					{
						dp[j][sum1]=c[x];
						x++;
					}
					else
					{
						dp[j][sum1]=d[y];
						y++;
					}
					if(dp[j][sum1]!=dp[j][sum1-1])//如果和上一个数不是重复数字,更新,
					{
						sum1++;
					}
				}
			}
		}
		printf("%lld\n",dp[v][k]);//输出第k个最大值
	}
	return 0;
}

发布了130 篇原创文章 · 获赞 3 · 访问量 1635

猜你喜欢

转载自blog.csdn.net/yeyuluo/article/details/103692956