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;
 } 

 

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