HDU4283 You Are the One —— 区间DP
题目链接:https://vjudge.net/problem/HDU-4283
You Are the One
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4667 Accepted Submission(s): 2218
The next n line are n integer D1-Dn means the value of diaosi of boys (0 <= Di <= 100)
5
1
2
3
4
5
5
5
4
3
2
2
Case #2: 24
题意:
有n个人站成一排准备上台表演,由于每个人都想是第一个站到台上,所以如果需要等待就会不开心。每个人都有一个值a[i],表示每等待一个人,不开心度就会+a[i]。工作人员为了使得所有人的不开心总值最小,就设置了一个小黑屋(一个栈),可以把队列的人先安排到小黑屋里,以此调节出场顺序。
题解:
1.可知:在一个区间 [l, r] 内, 如果l是第 k (1<=k<=r-l+1)个出场的,那么 [l+1, l+k-1] 必定是先与l出场的(根据栈的性质,如果要得到栈底元素,那么必须把栈底元素上面的所有元素出栈), 所以剩下的 [l+k, r] 是在l之后出场的。
2.根据第一条结论,如果确定了l在区间 [l, r] 是第k个出场的(不需要考虑区间之外的人),那么就可以把区间分为 [l+1, l+k-1] 和 [l+k, r],且这两个区间是互不影响的,所以又可以根据上述结论分别对这两个区间单独求值。
3.那怎么计算区间的不开心总值呢?
由于我们知道l在当前区间内是第k个出场的,所以我们可以先得到 a[l]*(k-1)。对于区间[l+1, l+k-1]的人,由于他们是先于l出场的,所以对于这个总体来说,他们是没有延迟的,所以直接加上dp[l+1, l+k-1]。对于区间[l+k, r]的人,由于他们是在l之后出场的,而l在这个区间内又是第k个出场的,所以对于 [l+k, r]这个总体来说,他们是整体延迟了k个人的,所以先加上 k*(sum[r]-sum[l+k-1]),加上了延迟所带来的不开心值之后,我们就可以把 区间[l+k, r]的出场是没有延迟的,所以情况跟区间[l+1, l+k-1]一样,再加上dp[l+k, r]就行了。
学习之处:
1.栈的性质: 如果要得到栈底元素,那么必须把栈底元素上面的所有元素出栈(这个结论虽然显而易见,但是由这个结论再推出另外的结论却并非易事)。
2.求值除了一步求得之外,还可以分步求值,一个阶段只求一部分。
记忆化搜索:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = +; int a[MAXN];
int sum[MAXN], dp[MAXN][MAXN]; int dfs(int l, int r)
{
if(l>=r) return ;
if(dp[l][r]!=-) return dp[l][r]; dp[l][r] = INF;
for(int k = ; k<=r-l+; k++)
{
int tmp = dfs(l+, l+k-)+dfs(l+k,r)+(k-)*a[l]+k*(sum[r]-sum[l+k-]);
dp[l][r] = min( dp[l][r], tmp );
}
return dp[l][r];
} int main()
{
int T, n, kase = ;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
sum[] = ;
for(int i = ; i<=n; i++)
scanf("%d", &a[i]), sum[i] = sum[i-]+a[i]; memset(dp, -, sizeof(dp));
dfs(, n);
printf("Case #%d: %d\n", ++kase, dp[][n]);
}
}
递推:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = +; int a[MAXN];
int sum[MAXN], dp[MAXN][MAXN]; int main()
{
int T, n, kase = ;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
sum[] = ;
for(int i = ; i<=n; i++)
scanf("%d", &a[i]), sum[i] = sum[i-]+a[i]; memset(dp, , sizeof(dp));
for(int len = ; len<=n; len++)
{
for(int l = ; l<=n-len+; l++)
{
int r = l+len-;
dp[l][r] = INF;
for(int k = ; k<=r-l+; k++)
{
int tmp = dp[l+][l+k-] + dp[l+k][r] + (k-)*a[l] + k*(sum[r]-sum[l+k-]);
dp[l][r] = min(dp[l][r], tmp);
}
}
}
printf("Case #%d: %d\n", ++kase, dp[][n]);
}
}
HDU4283 You Are the One —— 区间DP的更多相关文章
- hdu4283 You Are the One 区间DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4283 自己想了很久还是不会,参考了别人的思路才写的,区间DP还是很弱,继续努力!! 思路: 转载: 题 ...
- hdu-4283 You Are the One 区间dp,
题意:n个人排队上台,每个人有一屌丝值D,他的不满意值=D*(k-1)(k为他前面的总人数). 求整个队列不满意值之和的最小值.你只有一个操作,就是把队首的人塞进小黑屋,也就是压入栈中,后面的人就被提 ...
- hdu4283 区间dp
//Accepted 300 KB 0 ms //区间dp //dp[i][j] 表示i到j第一个出场的最小diaosizhi //对于i到j考虑元素i //(1)i第一个出场,diaosizhi为 ...
- HDU4283:You Are the One(区间DP)
Problem Description The TV shows such as You Are the One has been very popular. In order to meet the ...
- 【BZOJ-4380】Myjnie 区间DP
4380: [POI2015]Myjnie Time Limit: 40 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 162 Solved: ...
- 【POJ-1390】Blocks 区间DP
Blocks Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5252 Accepted: 2165 Descriptio ...
- 区间DP LightOJ 1422 Halloween Costumes
http://lightoj.com/volume_showproblem.php?problem=1422 做的第一道区间DP的题目,试水. 参考解题报告: http://www.cnblogs.c ...
- BZOJ1055: [HAOI2008]玩具取名[区间DP]
1055: [HAOI2008]玩具取名 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1588 Solved: 925[Submit][Statu ...
- poj2955 Brackets (区间dp)
题目链接:http://poj.org/problem?id=2955 题意:给定字符串 求括号匹配最多时的子串长度. 区间dp,状态转移方程: dp[i][j]=max ( dp[i][j] , 2 ...
随机推荐
- polya burnside 专题
polya题目:uva 11077 Find the Permutationsuva 10294 Arif in DhakaLA 3641 Leonardo's Notebookuva 11077 F ...
- h5表单验证的css和js方法
1.css3 提示只适用于高级浏览器: Chrome,Firefox,Safari,IE9+ valid.invalid.required的定义 代码如下: input:required, input ...
- 【shell】shell编程(三)-if,select,case语句
通过前两篇文章,我们掌握了shell的一些基本写法和变量的使用,以及基本数据类型的运算.那么,本次就将要学习shell的结构化命令了,也就是我们其它编程语言中的条件选择语句及循环语句. 不过,在学习s ...
- H5 折线图插件
一.可以使用Highcharts,参考网址:https://api.hcharts.cn/highcharts: 二.可以使用Echarts,参考网址:http://echarts.baidu.com ...
- VScode开发Vue初尝试(一)
由于公司近期有新的H5项目开发,而前端的同事也离职了,所以就临时顶缸,研究学习一下Vue框架开发. 本人也是初学,在学习过程中,把一些学习所得分享出来,可能会有很多问题和疏漏,希望大家能够多多指正,共 ...
- Google解决跨域
1.添加 --disable-web-security --user-data-dir=D:\tmp 2.在D的根目录新建tmp文件夹
- 洛谷——P1290 欧几里德的游戏
P1290 欧几里德的游戏 题目描述 欧几里德的两个后代Stan和Ollie正在玩一种数字游戏,这个游戏是他们的祖先欧几里德发明的.给定两个正整数M和N,从Stan开始,从其中较大的一个数,减去较小的 ...
- SGU 乱乱开
本解题报告 乱抄,乱写,随性随心,不喜多喷! SGU 142: 思路:一个string的字串不会超过2^20个,我们枚举出来就好了. 我出错点:数组RE #include<stdio.h> ...
- 某考试 T1 line
状压dp+矩阵转移,据说正解是dfs出的合法状态,,但难道不是三个for就行了吗2333 #include<iostream> #include<cmath> #include ...
- 深入GCD(五):资源竞争
概述我将分四步来带大家研究研究程序的并发计算.第一步是基本的串行程序,然后使用GCD把它并行计算化.如果你想顺着步骤来尝试这些程序的话,可以下载源码.注意,别运行imagegcd2.m,这是个反面教材 ...