hdu 4283 You Are the One

来源:互联网 发布:手机office软件下载 编辑:程序博客网 时间:2024/06/08 10:49

题目链接

分析:
一道区间dp。因为有栈的约束,这道题用贪心是不可行的。
令dp[l][r]表示原区间[l, r]的人最小的花费。这里的最小花费是去除了前l - 1个以及后N - r个的。
考虑[l, r]中,第一个人在区间中的排序。因为是第一个人,他的位置会把整个序列切成两块。于是把整个问题分成了两个子问题。
dp[l][r]=dp[l+1][k]+dp[k+1][r]+(kl)v[l]+(kl+1)k+1,rv[i]
最后一块是因为在[k + 1, r]之前加上了一块长度为k的序列,需要将后面的所有值后移k个单位。

代码:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cstdlib>#include <vector>#include <queue>#include <stack>using namespace std;const int maxn = 105;const int INF = 0x3f3f3f3f;int dp[maxn][maxn];int sum[maxn];int a[maxn];int N;int main(int argc, char const *argv[]) {    int T; cin>>T;    int kase = 1;    while (T --) {        memset(dp, 0, sizeof(dp));        cin>>N;        for (int i = 1; i <= N; i ++) {            scanf("%d", a + i);            sum[i] = sum[i - 1] + a[i];        }        for (int i = 1; i <= N; i ++)            for (int j = i + 1; j <= N; j ++)                dp[i][j] = INF;        for (int len = 1; len <= N - 1; len ++) {            for (int l = 1; l + len <= N; l ++) {                int r = l + len;                for (int k = l; k <= r; k ++)                    dp[l][r] = min(dp[l][r],                        dp[l + 1][k] + dp[k + 1][r]                            + (k - l) * a[l] + (k - l + 1) * (sum[r] - sum[k]));            }        }        printf("Case #%d: %d\n", kase ++, dp[1][N]);    }    return 0;}
0 0
原创粉丝点击