HDU 4283 You Are the One(区间DP)

来源:互联网 发布:java整形转换为字符串 编辑:程序博客网 时间:2024/05/29 02:34

Description

n个人轮流上台表演,每个人有一个屌丝值Di,如果第i个人第k个上台,他的不高兴值为(k1)Di,初始时这n个人按顺序站好,为了降低不高兴值,可以通过一个小黑屋(后进先出)调整这n个人上台的先后顺序,问这n的人的总不高兴值的最小值

Input

第一行一整数T表示用例组数,每组用例首先输入一整数n表示人数,之后n个整数Di表示第i个人的屌丝值(0<n100,0Di100)

Output

输出这n的人的总不高兴值的最小值

Sample Input

2
  
5
1
2
3
4
5

5
5
4
3
2
2

Sample Output

Case #1: 20
Case #2: 24

Solution

dp(l,r)表示第l到第r个人作为前rl+1个人上场的最小不高兴值,答案即为dp(1,n)

枚举第l个人的上场次序,如果第l个人在这rl+1个人中是第i(1irl+1)个上场的,由于是通过一个栈调整顺序,且进栈是按编号从小到大的,故第l个人后面的i1个人必然在第l个人上场前已经上场了,那么由第l个人产生的不高兴值即为(i1)Dl,第l+1到第l+i1i1个人产生的不高兴值为dp(l+1,l+i1),剩下的人产生的不高兴值为dp(l+i,r)+ij=l+irDj,加上第二部分的值是因为在这些人表演之前又多了i个人表演

Code

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define INF 0x3f3f3f3f#define maxn 111int T,n,a[maxn],sum[maxn],dp[maxn][maxn];int dfs(int l,int r){    if(l>=r)return 0;    if(dp[l][r]!=-1)return dp[l][r];    dp[l][r]=INF;    for(int i=l;i<=r;i++)        dp[l][r]=min(dp[l][r],(i-l)*a[l]+dfs(l+1,i)+dfs(i+1,r)+(i-l+1)*(sum[r]-sum[i]));    return dp[l][r];}int main(){    int res=1;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        sum[0]=0;        for(int i=1;i<=n;i++)scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];        memset(dp,-1,sizeof(dp));        printf("Case #%d: %d\n",res++,dfs(1,n));    }    return 0;}
原创粉丝点击