you are the one(区间dp)

Posted 小时のblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了you are the one(区间dp)相关的知识,希望对你有一定的参考价值。

传送门

You Are the One

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4042    Accepted Submission(s): 1876


Problem Description
  The TV shows such as You Are the One has been very popular. In order to meet the need of boys who are still single, TJUT hold the show itself. The show is hold in the Small hall, so it attract a lot of boys and girls. Now there are n boys enrolling in. At the beginning, the n boys stand in a row and go to the stage one by one. However, the director suddenly knows that very boy has a value of diaosi D, if the boy is k-th one go to the stage, the unhappiness of him will be (k-1)*D, because he has to wait for (k-1) people. Luckily, there is a dark room in the Small hall, so the director can put the boy into the dark room temporarily and let the boys behind his go to stage before him. For the dark room is very narrow, the boy who first get into dark room has to leave last. The director wants to change the order of boys by the dark room, so the summary of unhappiness will be least. Can you help him?
 

 

Input
  The first line contains a single integer T, the number of test cases.  For each case, the first line is n (0 < n <= 100)
  The next n line are n integer D1-Dn means the value of diaosi of boys (0 <= Di <= 100)
 

 

Output
  For each test case, output the least summary of unhappiness .
 

 

Sample Input
2    5 1 2 3 4 5 5 5 4 3 2 2
 

 

Sample Output
Case #1: 20 Case #2: 24
 
【题目大意】
n个人参加节目,每人都有一个屌丝值D,如果他第k个上场,那么他的不高兴值为(k-1)*D,因为他要等k-1个人。
节目有个小黑屋(是个栈,满足栈的性质)可以改变入场顺序。求最小不高兴值。
【思路】
区间dp。
现在上场的人的可能性有..栈顶的那个人,队伍中的那个人,队伍中的人进栈后,队首的那个人。
用dp[i][j]表示第i个人到第j个人的最小不高兴价值。
区间dp要进行区间合并,进行枚举断点k。
dp[i][j]由dp[i][k]和dp[k+1][j]转移而来。
可以第i--k个人先上舞台,k+1--j后上舞台。
也可以第k+1---j个人先上舞台,第i--k个人后上舞台,这就要求i--k这些人进栈,那么再上舞台的顺序就是原来的逆序,不高兴值预处理。
注意,对于dp[i][j]是个独立的区间,看成第i个就是这个区间的第一个进行处理。只需在合并时处理一下。
转移方程:
dp[i][j]=min(dp[i][j],min{dp[i][k]+dp[k+1][j]+(sum[j]-sum[k-1])*(k-i+1)  ,dp[k+1][j]+v[i][k]+(sum[k]-sum[i-1])*(j-k) }) 
转移方程指的是在上述两种情况中寻找最小值,其中sum是因为我们在处理dp[i][j]时是将i看做第一个处理的,
如果说i--k个先进入,k+1--j后进入(第一种情况),k+1--j每个人前面多了k-i+1个人,所以要加上产生的不高兴值。
记忆化搜索也可做。
最大值0x7fffffff(7个f为2147483647,3个f五位数)。
【code】
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define inf 0x7fffffff
int n,t,kas;
int sum[110],v[110][110],dp[110][110],a[110];
void befr() {
    for(int i=1; i<=n; i++)
        for(int j=i-1; j>=1; j--)
            v[j][i]=v[j+1][i]+a[j]*(i-j);
}
int main() {
    scanf("%d",&t);
    while(t--) {
        memset(sum,0,sizeof(sum));
        memset(v,0,sizeof(v));
        scanf("%d",&n);
        for(int i=1; i<=n; i++) {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        for(int i=0; i<=n; i++)
            for(int j=0; j<=n; j++)
                if(i!=j)
                    dp[i][j]=inf;
                else
                    dp[i][j]=0;
        befr();
        for(int j=1; j<=n; j++)
            for(int i=j-1; i>=1; i--)
                for(int k=i; k<j; k++) {
                    dp[i][j]=min(dp[i][j],min(dp[i][k]+dp[k+1][j]+(sum[j]-sum[k])*(k-i+1),dp[k+1][j]+v[i][k]+(sum[k]-sum[i-1])*(j-k)));
                }
        printf("Case #%d: %d\n",++kas, dp[1][n]);
    }
    return 0;
}

 

以上是关于you are the one(区间dp)的主要内容,如果未能解决你的问题,请参考以下文章

HDU4283:You Are the One(区间DP)

you are the one(区间dp)

hdu 4283 You Are the One(区间dp)

hdu 4283 You Are the One 区间dp

HDU 4283---You Are the One(区间DP)

(HDu 4283)You Are the One(区间DP)