hdu4283 You Are the One 区间DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4283
自己想了很久还是不会,参考了别人的思路才写的,区间DP还是很弱,继续努力!!
思路:
转载:
题解:想dp[i][j]表示[i ,j]内的unhappiness最小值,枚举k(i<=k<j),有两种情况需要讨论:
1 如果[i , k]区间内的人全部在[k+1, j]区间内的人之前出列,且已经全部不在栈中,即[i , j]区间可以分为[i , k] , [k+1 ,j]两个完全相同的子问题,
即dp[i][j] =MIN(dp[i][j] , dp[i][k] + dp[k+1][j] + (sum[j] – sum[i]) * (k – i +1));
2 如果[i , k]区间内的人全部在[k+1 , j]区间内的人之后出列,即[i , k]区间内的人全部需要进栈,所以出来的顺序是逆序的,需O(n2)预处理出against_order[i][j]
表示[i , j]区间人逆序出来的unhappiness值,即dp[i][j] = MIN(dp[i][j] , dp[k+1][j] + against_order[i][k] + (sum[k]– sum[i-1]) * (j - k));
我用了记忆化搜索和迭代两种方式实现,主要是为了加深自己的理解和记忆
记忆化搜索代码 :
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
using namespace std;
#define INF 1000010111
int n;
int a[];
int dp[][];
int sum[];
int order[][];
void Make_order()
{
memset(order,,sizeof(order));
for(int j=;j<=n;j++)
for(int i=j-;i>=;i--)
order[i][j]=order[i+][j]+a[i]*(j-i); }
int dfs(int i,int j)
{
if(dp[i][j]<INF) return dp[i][j];
if(i==j) return dp[i][j]=;
for(int k=i;k<j;k++)
dp[i][j]=min(dp[i][j],min(dfs(i,k)+dfs(k+,j)+(sum[j]-sum[k])*(k-i+),dp[k+][j]+order[i][k]+(sum[k]-sum[i-])*(j-k)));
return dp[i][j];
}
int main()
{
int t;
scanf("%d",&t);
int tol=;
while(t--)
{
sum[]=;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-]+a[i];
}
Make_order();
for(int i=;i<;i++)
for(int j=;j<;j++)
dp[i][j]=INF;
cout<<"Case #"<<tol++<<": "<<dfs(,n)<<endl;
} }
迭代代码:
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
using namespace std;
#define INF 100001000
int dp[][];
int a[];
int sum[];
int order[][];
int n;
void init()
{
scanf("%d",&n);
sum[]=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-]+a[i];
}
for(int i=;i<;i++)
for(int j=i;j<;j++)
if(i==j) dp[i][j]=;
else dp[i][j]=INF;
memset(order,,sizeof(order));
for(int j=;j<=n;j++)
for(int i=j-;i>=;i--)
order[i][j]=order[i+][j]+a[i]*(j-i);
} int main()
{
int t;
int tol=;
scanf("%d",&t);
while(t--)
{
init();
for(int j=;j<=n;j++)
for(int i=j-;i>=;i--)
{
for(int k=i;k<j;k++)
dp[i][j]=min(dp[i][j],min(dp[i][k]+dp[k+][j]+(sum[j]-sum[k])*(k-i+),dp[k+][j]+order[i][k]+(sum[k]-sum[i-])*(j-k)));
}
cout<<"Case #"<<tol++<<": "<<dp[][n]<<endl;
}
return ; }
hdu4283 You Are the One 区间DP的更多相关文章
- HDU4283 You Are the One —— 区间DP
题目链接:https://vjudge.net/problem/HDU-4283 You Are the One Time Limit: 2000/1000 MS (Java/Others) M ...
- 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 ...
随机推荐
- 开源 & 在线免费使用:升讯威 周报系统
这个周报系统大约写于2015年,缘起当时所带的开发团队需要逐步建立或完善一些项目管理方法. 在调研了网上的诸多项目管理或周报/日报管理系统之后,并没有找到符合当时情况的系统,这里最大的问题不是网上既有 ...
- 20. Valid Parentheses - 括号匹配验证
Description: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determin ...
- 模式识别(1)——PCA算法
作者:桂. 时间:2017-02-26 19:54:26 链接:http://www.cnblogs.com/xingshansi/articles/6445625.html 声明:转载请注明出处, ...
- ng自定义一个过滤器
ng允许我们自定义指令 下面来我们自己来定义一个过滤指令:filter,返回一个函数的形式 filter(name,callback(){//name:过滤器的名字,callback:匿名函数 ret ...
- 老李分享:大数据测试中java和hadoop关系
Hadoop的创始人是Doug Cutting, 同时也是著名的基于Java的检索引擎库Apache Lucene的创始人.Hadoop本来是用于著名的开源搜索引擎Apache Nutch,而Nutc ...
- hdu 2516 取石子游戏 (斐波那契博弈)
题意:1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍. 取完者胜,先取者负输出"Second win",先取者胜 ...
- 在多个Activity中回传值(startActivityForResult())
业务逻辑: MainActivity打开A,A打开B,B把值传回MainActivity.适用在多个Activity中回传值. 实例:微信中选择国家-->省份-->城市的实现 实现方式分析 ...
- 打印pid,写着玩。
#include <stdio.h> #include <string.h> #include <dirent.h> #include <limits.h&g ...
- 奇葩问题:同样的字符串equal为false
问题:什么情况下 "同样" 的字符串会不equal呢?例如 "a".equal("a") => false 在你看来,这可能是个 ...
- mysql自动备份删除5天前的备份
1.查看磁盘空间情况: # df -h 2.创建备份目录: 上面我们使用命令看出/home下空间比较充足,所以可以考虑在/home保存备份文件: cd /home mkdir backup cd ba ...