间接DP做法

比较好想到的是\(O(n m^2)\)的多维背包,由于这题有点卡空间,得把数组开成short类型。

正解:

\(dp_{i,j,k}\)表示前i个物体选j个物品画面质量综合为k时,不可玩度的最小值。
那转移方程为:
\(dp_{i,j,k}=max(dp_{i-1,j,k} \quad ,\quad dp_{i-1,j-1,k-a[i]}+b[i]\)

这跟我们以往的正常DP不同,我们让限制条件表示为DP结果,答案为DP的状态,从而间接得到了答案。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+107;
int n,A,B;
int a[85],b[85];
short f[81][81][N];
int main()
{
	scanf("%d%d%d",&n,&A,&B);
	for(int i=1;i<=n;i++)
	{
		cin>>a[i]>>b[i];
	}
	memset(f,0x7f,sizeof f);
	for(int i=0;i<=n;i++) f[i][0][0]=0;
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=i;j++)
		{
			for(int k=A;k>=0;k--)
			{
				
				f[i][j][k]= (f[i-1][j-1][k-a[i]]+b[i]<f[i-1][j][k]) ? (f[i-1][j-1][k-a[i]]+b[i]) : f[i-1][j][k];
				if(k<a[i]) f[i][j][k]=max(f[i-1][j][k],f[i][j][k]);
				if(f[i][j][k]<=B) ans=max(ans,j);
			}
		}
	}
	
	cout<<min(ans+1,n)<<"\n";
}
posted @ 2024-08-13 08:28  zhengchenxi  阅读(28)  评论(0)    收藏  举报