HDU 4283 You Are the One(区间dp)

来源:互联网 发布:淘宝宝贝分类在哪里 编辑:程序博客网 时间:2024/05/18 20:52
/*data: 2016/11/08writer: cn_swords题意:有n个男按顺序排好,每个人都有一个值D[i],如果第i个人第k个上台找对象,那么该男的不开心值就会为(k-1)*D[i],小黑屋是个栈,上台顺序可以通过小黑屋改变,求最小不开心值;题解:dp[l][r]代表区间(l,r)里,最小的不开心值,dp[l][r],寻找一个k,让第l人第k个上场,使得dp[l][r]取得最小值(sum[r]-sum[l+k-1])*k 表示:sum[i]用来记录前面i个人的总不开心值,每个人的值是个累加的过程,多等一个人,就多累加一次dp[l][r] = dp[l+1][l+k-1]+dp[l+k][r]+(k-1)*a[l]+(sum[r]-sum[l+k-1])*k;*/#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int INF = 0x3f3f3f3f;const int N = 105;int a[N];int sum[N];int dp[N][N];int main(){    int T,cas = 1;    scanf("%d",&T);    while(T--)    {        int n;        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,0,sizeof(dp));        for(int len = 1; len < n; len++)        {            for(int l = 1; l+len <= n; l++)            {                int r = l+len;                dp[l][r] = dp[l+1][r]+sum[r]-sum[l];                for(int k = l+1; k <= r; k++)                    dp[l][r] = min(dp[l][r],dp[l+1][k]+dp[k+1][r]+(k-l)*a[l]+(sum[r]-sum[k])*(k-l+1));            }        }        printf("Case #%d: %d\n",cas++,dp[1][n]);    }    return 0;}
0 0
原创粉丝点击