hdu 4283"You Are the One"(区间DP)

Posted violet-acmer

tags:

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

传送门

https://www.cnblogs.com/violet-acmer/p/9852294.html

 

题意:

  有n个屌丝排成一排,每个屌丝都有一个不开心值a[ i ]( i=1,2,3,.....n ),如果第 i 个屌丝第 k 个上场,那么他的不开心度就是(k-1)*a[ i ]。

  ∑ni=1(ki-1)*a[i]的最小值,其中ki指的是第i个屌丝第k个上场。

  关键条件"the director can put the boy into the dark room temporarily and let the boys behind his go to stage before him.",意思是导演可以通过将某个屌丝 i

  之前的屌丝 j 放入小黑屋中使屌丝 i 在屌丝 j 前上场,不过这个小黑屋非常狭窄,先进入的最后上场,就像栈一样。

  通过样例解释一下这句话:

  假设有5的屌丝

  id : 1  2  3  4  5

  a[]: 5  8  3  9  4

  按照当前的顺序,屌丝4是第4个上场的,如果想要让屌丝4第一个入场,那么,就需要将屌丝1,2,3依次放入小黑屋中,那么,屌丝1,2,3的上场顺序就是3,2,1。

题解:

  定义变量dp[ i ][ j ] : ∑ji=1(ki-1)*a[i]的最小值( 1≤ki≤len,len=j-i+1(当前区间屌丝人数) )。

  对于区间[ i, j ],屌丝 i 可以第 k 个上场,那么,其之后的相邻的 k-1 个屌丝一定在他之前全部上场,且他之前只有这 k-1 个屌丝上场,那么前 k 个屌丝的当前最小的

  不开心度就是 (k-1)*a[ i ]+dp[ i+1 ][ i+k-1 ],那么余下的 len-k 个屌丝的最小不开心度就是 dp[ i+k ][ j ]+k*( sum(j)-sum(i+k-1) );(sum[ ]是屌丝不开心值的前缀和)。

  所以dp转移方程就是 : dp[ i ][ j ]=min( dp[ i ][ j ],(k-1)*a[ i ]+dp[ i+1 ][ i+k-1 ] dp[ i+k ][ j ]+k*( sum(j)-sum(i+k-1) ) );

AC代码:

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>|
 3 #include<cstring>
 4 using namespace std;
 5 #define mem(a,b) memset(a,b,sizeof(a))
 6 #define INF 0x3f3f3f3f
 7 const int maxn=100+10;
 8 
 9 int n;
10 int a[maxn];
11 int dp[maxn][maxn];
12 int sum[maxn];
13 
14 int Solve()
15 {
16     mem(dp,0);
17     for(int i=1;i < n;++i)
18         for(int j=i+1;j <= n;++j)
19             dp[i][j]=INF;
20 
21     for(int len=2;len <= n;++len)
22     {
23         for(int i=1;i+len-1 <= n;++i)
24         {
25             int j=i+len-1;
26             for(int k=1;k <= (j-i+1);++k)
27                 dp[i][j]=min(dp[i][j],(k-1)*a[i]+dp[i+1][i+k-1]+dp[i+k][j]+k*(sum[j]-sum[i+k-1]));
28         }
29     }
30     return dp[1][n];
31 }
32 int main()
33 {
34     int t;
35     scanf("%d",&t);
36     for(int kase=1;kase <= t;++kase)
37     {
38         scanf("%d",&n);
39         sum[0]=0;
40         for(int i=1;i <= n;++i)
41         {
42             scanf("%d",a+i);
43             sum[i]=sum[i-1]+a[i];
44         }
45         printf("Case #%d: %d
",kase,Solve());
46     }
47     return 0;
48 }
View Code

 

以上是关于hdu 4283"You Are the One"(区间DP)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 4283You Are the One

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

刷题总结——you are the one(hdu4283)

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

HDU4283:You Are the One(区间DP)

hdu 4283 You Are the One 区间dp