You Are the One HDU - 4283

原题链接

考察:区间dp

转移方程没想出来,思路参考大佬们的题解

错误思路:

       本题主要难在[i,j]区间取走某一个数k时,我们要考虑继续往后取还是往前取,如果取前面的就只能取尾端,这就与我们一开始的子结构不符.所以此思路设置间断点划分集合行不通.

正确思路:

       f[i,]表示i~j人走花费的时间.考虑将区间[i,j]看成一个栈,如果已知栈底i是第k个走的,那么[i+1,i+k-1]必须在他之前走,而这个区间又是符合我们确定的子结构的.那么后半部分[i+k,j]必须先等(sum[j]-sum[i+k-1])*k后,又可以看成一个栈.这也是符合我们划分的子结构的.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 const int N = 110;
 7 int a[N],f[N][N],sum[N];
 8 int main()
 9 {
10     int T,kcase = 0;
11     scanf("%d",&T);
12     while(T--)
13     {
14         int n; memset(f,0,sizeof f);
15         scanf("%d",&n);
16         for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
17         for(int len=2;len<=n;len++)
18            for(int l=1;l+len-1<=n;l++)
19            {
20                  int r = l+len-1; f[l][r] = 0x3f3f3f3f;
21                  for(int k=1;k<=r-l+1;k++)
22                    f[l][r] = min(a[l]*(k-1)+f[l+1][l+k-1]+f[l+k][r]+(sum[r]-sum[l+k-1])*k,f[l][r]);
23            }
24         printf("Case #%d: %d\n",++kcase,f[1][n]);
25     }
26     return 0;
27 }

 

2021.3.17 二刷,真的完全想不到...这道题是求最优出栈过程.第二次看这题反应是这也能区间dp  ,不能以k是第1个走的划分集合,因为f[l][k-1]已经不是与f[l][r]的相同子结构了.这道题以栈底是第k个走的,更小的区间子结构与i,j相同.

posted @ 2021-02-12 02:16  acmloser  阅读(67)  评论(0编辑  收藏  举报