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

http://acm.hdu.edu.cn/showproblem.php?pid=4283

题意:有n个数字,不操作的情况下从左到右按顺序输出,但是可以先让前面的数字进栈,让后面的数字输出,然后栈里的数字再输出。执行完各种操作后,第i个数字输出的代价是w[i] * (i-1)。问如何弄才能使得代价最小,输出。

思路:做了半个下午。好菜啊QAQ。

考虑两种情况:

1、左区间的元素先输出,然后右区间的元素再输出。这个时候方程为 dp[i][j] = dp[i][k] + dp[k+1][j] + sum(k+1,j) * (i-k+1)。

2、左区间的元素进栈,右区间的元素先输出,然后左区间元素倒序输出(因为进了栈顺序反了)。方程为 dp[i][j] = dp[k+1][j] + sum(i,k) * (j-k) + tmp.(tmp是倒序输出的代价)

然后对于这两种情况取优就好了。

都是细节没搞清楚才做好久。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 #define N 105
 6 typedef long long LL;
 7 LL dp[N][N], w[N], pre[N];
 8
 9 int main() {
10     int t, cas = 0;
11     scanf("%d", &t);
12     while(t--) {
13 //        char s[2];
14 //        if(cas == 0) scanf("%s", s);
15         int n; scanf("%d", &n);
16         memset(dp, 0x3f3f3f3f, sizeof(dp));
17         for(int i = 1; i <= n; i++) scanf("%lld", &w[i]), dp[i][i] = 0;
18         for(int i = 1; i <= n; i++) pre[i] = pre[i-1] + w[i];
19         for(int len = 1; len < n; len++) {
20             for(int i = 1; i + len <= n; i++) {
21                 int j = i + len;
22                 for(int k = i; k < j; k++) {
23                     // a的情况是前后的区间都不入栈
24                     LL a = dp[i][k] + dp[k+1][j] + (pre[j] - pre[k]) * (k + 1 - i);
25                     LL tmp = 0;
26                     for(int cnt = k; cnt >= i; cnt--) tmp += w[cnt] * (k - i);
27                     // tmp 求倒着出栈的代价
28                     // b的情况是前面的入栈,让后面的区间直接出来
29                     LL b = dp[k+1][j] + (pre[k] - pre[i-1]) * (j - k) + tmp;
30                     dp[i][j] = min(dp[i][j], min(a, b));
31                 }
32             }
33         }
34         printf("Case #%d: %lld\n", ++cas, dp[1][n]);
35     }
36     return 0;
37 }
时间: 2024-12-25 08:42:42

HDU 4283:You Are the One(区间DP)的相关文章

HDU 4283 You Are the One 区间dp

题意: 题意好复杂... 给定n个人,从左到右排好队. 他们依次从左到右离开队伍. 每个人有个权值d 当某个人是第k-th离开队伍的,那么不开心值为 d*(k-1) 有一个操作,对于一个子序列,可以把前面一段翻转. 问最小的不开心值和. #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<vector> #include<q

hdu 4283&quot;You Are the One&quot;(区间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 temporari

HDU 4283 (第k个出场 区间DP)

http://blog.csdn.net/acm_cxlove/article/details/7964594 http://www.tuicool.com/articles/jyaQ7n http://blog.csdn.net/woshi250hua/article/details/7973824 记忆化搜索(15MS): #include <iostream> #include <string> #include <cstring> #include <cs

hdu 4632 子字符串统计的区间dp

题意:查找这样的子回文字符串(未必连续,但是有从左向右的顺序)个数. 简单的区间dp,哎,以为很神奇的东西,其实也是dp,只是参数改为区间,没做过此类型的题,想不到用dp,以后就 知道了,若已经知道[0,i],推[0,i+1], 显然还要从i+1 处往回找,dp方程也简单: dp[j][i]=(dp[j+1][i]+dp[j][i-1]+10007-dp[j+1][i-1])%10007; 减去中间一段重复的 if(s[i]==s[j])dp[j][i]=(dp[j][i]+dp[j+1][i-

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

题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=4283 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

HDU 5900 QSC and Master (区间DP)

题目链接   http://acm.hdu.edu.cn/showproblem.php?pid=5900 题意:给出序列Ai.key和Ai.value,若当前相邻的两个数Ai.key和Ai+1.key的最大公约数大于1,则可以把这两个数消去,同时消去Ai.value和Ai+1.value,每次消去得到的分数为Ai和Ai+1的value值,问最大可能得分. 注意:当Ai和Ai+1被消去后,Ai-1和Ai+2成为了新的相邻的数.若符合条件则可以继续消去. 思路:很明显是区间DP,但是我比赛中如何也

HDU 5151 Sit sit sit(区间DP)

HDU 5151 Sit sit sit 题目链接 区间DP+组合计数问题,转移方程为,每次选当前区间最后一个放的位置,然后乘上组合数C[区间长度][左区间长度] 代码: #include <cstdio> #include <cstring> typedef long long ll; const ll MOD = 1000000007; const int N = 105; int n, a[N]; ll dp[N][N], C[N][N]; int main() { C[1]

HDU 5396 Expression (MUT#9 区间DP)

[题意]:click here~~ [题目大意]: 给你一个一行包含n(2=<n<=100)个数字的式子,和一个字符串(2=<s<=100),字符串里包含三种运算符号:+,-,*,且s=n-1,也就是说在每两个数字之间,插入n-1个符号,位置已经在输入的时候固定了,现在你要做的就是可以自由安排符号的运算顺序,每轮选择之后,将会得到一个结果,求所有的结果的和 [思路]:区间DP: 先贴一下题解(感觉题解有个地方写错了): 设DP[l][r]:表示区间[l,r]这段里面能形成的答案的总

[hdu contest 2019-07-29] Azshara&#39;s deep sea 计算几何 动态规划 区间dp 凸包 graham扫描法

今天hdu的比赛的第一题,凸包+区间dp. 给出n个点m个圆,n<400,m<100,要求找出凸包然后给凸包上的点连线,连线的两个点不能(在凸包上)相邻,连线不能与圆相交或相切,连线不能相交但是可以有公共端点. 首先找出凸包,然后把n*n条边和m个圆算点到直线距离验证一下边是否与圆相交存到e[n][n]里. 然后显然是一个dp,但是我开始看错题目了以为不能有公共端点,能有公共端点的情况考虑一下像一个找三角形的过程,就是区间dp. 区间dp有一点妙的地方是最大区间范围是凸包点数而不用+1,因为连

HDU 4283 You Are the One (区间dp)

HDU 4283 题意:有n个男屌丝依次排队要登台,如果某个男屌丝前面排有k个人,则该屌丝很生气,生气程度 = (k-1)*D(D代表屌丝程度).现在有一个小黑屋,小黑屋先进后出,如果把某屌丝放进去,那么他后面的人就能先登台.给出每个人的屌丝程度与原定上台顺序,求怎样利用小黑屋,能够使众屌丝生气程度之和最小,求出最小值. 思路: #define 愤怒值 生气程度 dp[i][j]表示从第i个屌丝到第j个屌丝这段区间的min(sum(愤怒值))(假设只有这j-i+1个屌丝) 那么对于dp[i][j