BZOJ1652&&洛谷P2858 [USACO06FEB]奶牛零食Treats for the Cows

一道不是很简单的入门dp

我们发现当前操作只有从左侧取一个或者从右面取一个,那么我们转移肯定是需要上一次操作的这两个方案,我们定义f[i][j]表示一共取了i个,在左面取了j个,那么右面就取了i-j个,那么显然f[i][j]=max(f[i-1][j]+a[n-i+j+1]*i(这次从右侧取),f[i-1][j-1]+a[j]*i(这次从左侧取)),然后我们在最后循环一遍左侧取多少时有最大结果就好了

代码

//By AcerMo
#include<iostream>
using namespace std;
int n,a[2050],f[2050][2050];
int main()
{
	cin>>n;int ans=0;
	for (int i=1;i<=n;i++) cin>>a[i];
	for (int i=1;i<=n;i++)
	for (int j=0;j<=i;j++)
		f[i][j]=max(f[i-1][j]+a[n-i+j+1]*i,f[i-1][j-1]+a[j]*i);
	for (int i=1;i<=n;i++) ans=max(ans,f[n][i]);
	cout<<ans;
	return 0;
}

 

相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页