HDU 4283 You Are the One【区间dp】

题意:n个人排成一排,每个人轮流上场,第i个人上场有(i-1)*a【i】的愤怒值,有一个小黑屋,你可以把人塞进去,先进的后出来,求最小的愤怒值。

dp不亏是dp真难(可能是我太菜了。。。感觉写了不少了但还是很难自己写出来,菜哭

题解;区间dp,断点k代表的是第i个人第几次出场。

dp【i】【j】=min(dp【i】【j】,dp【i+1】【i+k-1】+(k-1)*a【i】+dp【i+k】【j】+k*(b【j】-b【i+k-1】)

b数组是a的累加。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define ll long long 
ll a[206],b[206],dp[206][206];
int main()
{
	int t;
	cin>>t;int o=0;
	while(t--)
	{
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		
		int n;
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
			b[i]=b[i-1]+a[i];
		}
		for(int i=0;i<=n+2;i++)
		{
			for(int j=i+1;j<=n+2;j++)
			{
				dp[i][j]=213456789;
				if(i==j)
				dp[i][j]=0;
			}
		}
		for(int len=2;len<=n;len++)
		{
			for(int i=1;i+len-1<=n;i++)
			{
				int j=i+len-1;
				for(int k=1;k<=j-i+1;k++)
				{
					dp[i][j] = min(dp[i][j], dp[i+1][i+k-1] + a[i] * (k-1) + dp[i+k][j] + k * (b[j] - b[i+k-1]));
				}
			}
		}
		printf("Case #%d: ",++o); 
		printf("%lld\n",dp[1][n]);
	 } 
	return 0;
 } 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章