hdu 4283 区间dp

You Are the One

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

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

网络赛的题目还真是难理解

题意我就不说了 说下理解吧。

一开始想的时候一直在想怎么维护栈(就是那个黑屋子),然后处理的细节太多不靠谱。这里卡了好久,后来发现思考的方向出了问题

其实每一个男生在上台的时候 最极端的情况有两种 一种是前面的男孩都在小黑屋子里候着,在就是小黑屋子里一个人都没有。其他情况就是在这两种极端情况之间咯,那么这个将要上台男生的上台次序我们就可以枚举确定了, 这一步理解了,就发现是一个典型的区间dp题目了

我们定义dp[i][j]表示序列 i~j的男生上台的最小花费 具体的状态转移看代码~

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int inf=100000009;
int main()
{
    int t;
    cin>>t;
    for(int Case=1;Case<=t;Case++)
    {
        int n;
        cin>>n;
        int a[101],sum[101];
        cin>>a[1];
        sum[1]=a[1];
        for(int i=2;i<=n;i++)
        {
            cin>>a[i];
            sum[i]=sum[i-1]+a[i];
        }
        int dp[120][120];// 注意这里的次序大小都是相对大小 ,不是绝对大小
        memset(dp,0,sizeof(dp));
        for(int l=2;l<=n;l++)
        {
            for(int i=1;i+l-1<=n;i++)
            {
                int j=i+l-1;
                dp[i][j]=inf;
                for(int k=1;k<=l;k++)//枚举i是第几个上场的
                {
                    int temp=i+k;//确定位置
                   /*
                考虑第K个上场即在i+1之后的K-1个人是率先上场的,那么就出现了一个子问题 dp[i+1][temp]表示在第i个人之前上场的
                 对于第i个人,由于是第k个上场的,那么愤怒值便是a[i]*(k-1)
                 其余的人是排在第k+1个之后出场的,也就是一个子问题dp[temp][j],对于这个区间的人,由于排在第k+1个之后,所以整体愤怒值要加上k*(sum(temp-1))
                    */
                    dp[i][j]=min(dp[i][j],dp[i+1][temp-1]+dp[temp][j]+a[i]*(k-1)+(sum[j]-sum[temp-1])*k);
                }
            }
        }
        printf("Case #%d: %d\n",Case,dp[1][n]);
    }
    return 0;
}

  dp不能急~ 慢慢啃~

时间: 2024-10-20 10:58:01

hdu 4283 区间dp的相关文章

hdu 5396 区间dp+组合

http://acm.hdu.edu.cn/showproblem.php?pid=5396 Problem Description Teacher Mai has n numbers a1,a2,?,anand n?1 operators("+", "-" or "*")op1,op2,?,opn?1, which are arranged in the form a1 op1 a2 op2 a3 ? an. He wants to erase

HDU 5115 区间DP

有n只狼,每只狼有两种属性,一种攻击力一种附加值,每杀一只狼 受到的伤害值为这只狼的攻击值与它旁边的两只狼的附加值的和,求把所有狼都杀光受到的最小的伤害值. 注意:如果杀死中间的狼,两边的狼会紧凑过来,也就是说中间不存在空位 很明显的区间DP dp[i][k]=Min(dp[i][k],dp[i][l-1]+dp[l+1][k]+a[l]+b[i-1]+b[k+1]); // i位置起始到k位置,最后杀死k位置的狼 #include "stdio.h" #include "s

2016 ACM/ICPC Asia Regional Shenyang Online 1009/HDU 5900 区间dp

QSC and Master Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 859    Accepted Submission(s): 325 Problem Description Every school has some legends, Northeastern University is the same. Enter

HDU 5273 区间DP

输入一组数,m次询问 问每一个询问区间的逆序数有多少 区间DP简单题 #include "stdio.h" #include "string.h" int dp[1010][1010],a[1010]; int main() { int n,m,i,j,k; while (scanf("%d%d",&n,&m)!=EOF) { for (i=1;i<=n;i++) scanf("%d",&a[i]

HDU 5396 区间DP 数学 Expression

题意:有n个数字,n-1个运算符,每个运算符的顺序可以任意,因此一共有 (n - 1)! 种运算顺序,得到 (n - 1)! 个运算结果,然后求这些运算结果之和 MOD 1e9+7. 分析: 类比最优矩阵链乘,枚举区间[l, r]中最后一个运算符的位置k. 如果运算符为乘法的话,那么根据乘法分配率这个乘法会分配进去. 这个区间中一共有r - l个运算符,其中最后一个运算符已经定了是第k个,左区间[l, k]有k - l个运算符,右区间[k + 1, r]有 r - k - 1 个运算符. 而且左

hdu 4293 区间DP

1 /* 2 题目大意:n个人分成若干组,每个人都描叙他们组前面有多少人后面有多少人, 3 求说真话的人最多有多少个. 4 解题思路:把同一组的人数统计起来他们组前面有x人后面有y人, 5 num[x+1][n-y]表示区间[x+1,n-y]的权值,num[x+1][n-y]<=n-x-y 6 那么就是求不重合,[1,n]区间的最大值 7 */ 8 #include <iostream> 9 #include <cstdio> 10 #include <cstring&

hdu 4745 区间dp

题意:求一个环的最长回文序列,是序列不是串 链接:点我 起点是可以任意的, 所以只要求出每个区间的最长回文序列之后取max(dp[1][i]+dp[i+1][n]),即可得最终答案 本来是想扩展两倍的,但是后来的最大不太好想 将 环倍增成链,求出窗口为n的最长子序列,但这不是最终的解,你可以试看看Sample 2,是只能得出4,因为它在选中的回文外面还可以选中一个当做起点来跳,所以外面得判断找出来的回文外面是否还有可以当起点的石头,即可以找窗口为(n- 1)的长度+1.所以解即找 窗口为n的长度

hdu 4632区间dp

给你一个字符串  让你求最大回文子序列的个数:dp[i][j]表示i到j的最大回文子序列个数(注意是个数,就要有累加过程  如果是最大长度  就直接赋值) 首先dp[i][j]=dp[i+1][j]+dp[i][j-1] 中间有重复的()就是与i+1余j-1无关的   所以还得减去dp[i+1][j-1] 然后判断str[i]与str[j]是否相等,如果是再加上dp[i+1][j-1]+1: #include<stdio.h> #include<string.h> #include

hdu 2476 区间dp

题意是让你把第一个字符串变为第二个的最小步数,具体变法就不说了, 假设第一个和第二个串对应位置全都不一样,那就先不考虑串1了,dp[i][j]i到j的最小步数:很显然开始dp[i][j]=dp[i+1][j] 我是从后往前跑的,如果中间处在相等比如str[i]=str[k] 则dp[i][k]=dp[i+1][k]  因为如果刷i到k-1要x步刷i+1到k要y步,现在str[i]==str[k]   如果第k个不和第i个一起刷  及先刷i再刷i+1到k-1 再刷k 则需要x+1步 其实如果i和k