【洛谷P1430】序列取数【dp】

题目大意:

题目链接:https://www.luogu.org/problemnew/show/P1430
给定一个长为n的整数序列,由A和B轮流取数(A先取)。每个人可从序列的左端或右端取若干个数(至少一个),但不能两端都取。所有数都被取走后,两人分别统计所取数的和作为各自的得分。假设A和B都足够聪明,都使自己得分尽量高,求A的最终得分。


思路:

时限3s3s,显然是要一个常数小的O(Tn2)O(Tn^2)的方法。
由于每次A和B都只可以在左右两端取数,所以取完后剩余的一定是一个连续的子区间。
正序做似乎不是很好做,考虑倒序,将问题转化成一个区间问题。
先考虑最暴力的方法,若先手取时剩余区间为[l,r][l,r],那么后手一定是取了[x,r][x,r][l,x](l<x<r)[l,x](l< x < r),然后先手取[l,x1][l,x-1][x+1,r][x+1,r]
dp[i][j]dp[i][j]表示先手取成[l,r][l,r]的最优答案,那么这个答案一定由后手的最劣方案转移而来。因为若后手取后的区间和为ss',区间[l,r][l,r]的和为ss,那么先手取的和为sss-s'。我们要让sss-s'尽量大,那么就让ss'尽量小即可。即后手的最劣方案。
所以转移方程就是
dp[i][j]=sum[j]sum[i1]min(0,dp[i][i],dp[i][i+1],...,dp[i][j1],dp[j][j],dp[j1][j],...,dp[i+1][j])dp[i][j]=sum[j]-sum[i-1]-min(0,dp[i][i],dp[i][i+1],...,dp[i][j-1],dp[j][j],dp[j-1][j],...,dp[i+1][j])
其中sum[i]sum[i]a[i]a[i]的前缀和,sum[j]sum[i1]sum[j]-sum[i-1]k=ija[k]sum^{j}_{k=i}a[k];加上0的原因是因为先手可以一次把所有选完,那么后手就不能选,即选的和为0。
这样单次询问的复杂度是O(n3)O(n^3)的。
看到方程中有minminminmin需要O(n)O(n)的复杂度,但是dpdp中的minmin一般都是可以进行转移的。所以可以通过转移minmin来去掉这个O(n)O(n)
f[i][j]=min(dp[i][i],dp[i][i+1],...,dp[i][j]),g[i][j]=min(dp[j][j],dp[j1][j],...dp[i][j])f[i][j]=min(dp[i][i],dp[i][i+1],...,dp[i][j]),g[i][j]=min(dp[j][j],dp[j-1][j],...dp[i][j])
方程就变成了
dp[i][j]=sum[j]sum[i1]min(0,f[i+1][j],g[i][j1])dp[i][j]=sum[j]-sum[i-1]-min(0,f[i+1][j],g[i][j-1])
f,gf,g的维护都是最最最最基础的了。显然有f[i][j]=min(f[i+1][j],dp[i][i])f[i][j]=min(f[i+1][j],dp[i][i])gg同理。
这样单次询问的复杂度就降到了O(n2)O(n^2)。总时间复杂度就是O(Tn2)O(Tn^2)。而且区间dpdp的常数好像还是12frac{1}{2}


代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=1010;
int T,n,a[N],sum[N],dp[N][N],f[N][N],g[N][N];

int main()
{
	scanf("%d",&T);
	while (T--)
	{
		scanf("%d",&n);
		for (int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			sum[i]=sum[i-1]+a[i];
			dp[i][i]=f[i][i]=g[i][i]=a[i];
		}
		for (int i=n-1;i>=1;i--)
			for (int j=i+1;j<=n;j++)
			{
				dp[i][j]=sum[j]-sum[i-1]-min(0,min(f[i+1][j],g[i][j-1]));
				g[i][j]=min(g[i][j-1],dp[i][j]);
				f[i][j]=min(f[i+1][j],dp[i][j]);
			}
		printf("%d
",dp[1][n]);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998137.html