http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3541

题意:
有一排开关,有个开关有两个值t和d,t是按下开关后在t秒后会自动弹起,d为距离最左端点的距离。问是否能找到一个按开关的顺序使得在某一时刻所有开关都打开。

思路:

首先要找一个最优子结构性质。

对于区间【l,r】来说,我们可以从任意一点出发,现在如果我们从中间的一点出发,那么必然要先去一个端点,然后再去另一个端点,那么在这个过程中,有些开关可能会经过多次,比如从出发点去左端点的过程中,可以打开路上的开关,但是我们还必须去右端点,那么在去右端点的路上,这些开关又会经过,此时又可以打开它,那么晚按肯定比早按来得更好,也就是说,从端点出发和从中间任意一点出发的效果是一样的,但是更省时间,这样一来,对于区间【l,r】,肯定是从端点出发的。

这样一来,用d【l】【r】【0/1】表示从左/右端点出发打开所有开关所需的最少时间。

如果从左端点出发,然后t【l】<=d【l】【r】【0/1】,那么就说明此时是无法打开区间内的所有开关的。

同时记录好路径即可。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef long long ull;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn = + ; int n;
int t[maxn];
int d[maxn]; int dp[maxn][maxn][];
int path[maxn][maxn][]; int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d",&n))
{
memset(dp,,sizeof(dp));
memset(path,-,sizeof(path)); for(int i=;i<=n;i++) scanf("%d",&t[i]);
for(int i=;i<=n;i++)
{
scanf("%d",&d[i]);
dp[i][i][]=dp[i][i][]=;
} for(int r=;r<=n;r++)
{
for(int i=;i+r-<=n;i++)
{
int j=i+r-;
dp[i][j][]=min(dp[i+][j][]+d[i+]-d[i],dp[i+][j][]+d[j]-d[i]);
path[i][j][]=(dp[i+][j][]+d[i+]-d[i]>=dp[i+][j][]+d[j]-d[i]);
if(dp[i][j][]>=t[i] || dp[i][j][]>INF)
dp[i][j][]=INF; dp[i][j][]=min(dp[i][j-][]+d[j]-d[i],dp[i][j-][]+d[j]-d[j-]);
path[i][j][]=(dp[i][j-][]+d[j]-d[i]>=dp[i][j-][]+d[j]-d[j-]);
if(dp[i][j][]>=t[j] || dp[i][j][]>INF)
dp[i][j][]=INF;
}
} int l=,r=n;
int next_p;
if(dp[][n][]<INF)
{
printf("");
l++;
next_p=path[][n][];
}
else if(dp[][n][]<INF)
{
printf("%d",n);
r--;
next_p=path[][n][];
}
else
{
puts("Mission Impossible");
continue;
} while(l<=r)
{
if(next_p)
{
printf(" %d",r);
next_p=path[l][r--][];
}
else
{
printf(" %d",l);
next_p=path[l++][r][];
}
}
printf("\n");
}
return ;
}

ZOJ 3541 The Last Puzzle(经典区间dp)的更多相关文章

  1. POJ 1651 Multiplication Puzzle (区间DP,经典)

    题意: 给出一个序列,共n个正整数,要求将区间[2,n-1]全部删去,只剩下a[1]和a[n],也就是一共需要删除n-2个数字,但是每次只能删除一个数字,且会获得该数字与其旁边两个数字的积的分数,问最 ...

  2. Poj 1651 Multiplication Puzzle(区间dp)

    Multiplication Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10010   Accepted: ...

  3. POJ1651Multiplication Puzzle(区间DP)

    比较好做的区间DP 状态转移方程:DP[i][j] 表示区间[i,j]最小的乘积和. DP[i][j] = MIN{DP[i][k-1]+DP[k+1][j] + a[k]*a[i-1]*a[j+1] ...

  4. POJ 1160 经典区间dp/四边形优化

    链接http://poj.org/problem?id=1160 很好的一个题,涉及到了以前老师说过的一个题目,可惜没往那上面想. 题意,给出N个城镇的地址,他们在一条直线上,现在要选择P个城镇建立邮 ...

  5. POJ 1651:Multiplication Puzzle(区间DP)

    http://poj.org/problem?id=1651 题意:给出n个数字,每取中间一个数,就会使得权值加上中间这个数和两边的乘积,求取剩两个数最少的权值是多少. 思路:区间dp. 一开始想了挺 ...

  6. ZOJ 1602 Multiplication Puzzle(区间DP)题解

    题意:n个数字的串,每取出一个数字的代价为该数字和左右的乘积(1.n不能取),问最小代价 思路:dp[i][j]表示把i~j取到只剩 i.j 的最小代价. 代码: #include<set> ...

  7. POJ 1651 Multiplication Puzzle (区间DP)

    Description The multiplication puzzle is played with a row of cards, each containing a single positi ...

  8. UVALive - 5695 The Last Puzzle (思维+区间dp)

    题目链接 题目大意:有n个按钮排成一条直线,你的任务是通过左右移动按下所有按钮,按钮如果一段时间没有被按下就会被弹开. 以下是我的推论(不一定正确): 直观地看的话,如果选择的是最优路径,那么路径的形 ...

  9. POJ1651:Multiplication Puzzle(区间dp)

    Multiplication Puzzle Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9419 Accepted: 5850 ...

随机推荐

  1. python 进行抓包嗅探

    一.绪论 最近一直想弄一个代理,并且对数据包进行解读,从而完成来往流量的嗅探.于是今天学习了一下如何使用Python抓包并进行解包. 首先要用到两个模块 dpkt(我这边ubuntu16.04 LTS ...

  2. angularJS中的ng-repeat指令!

    ng-repeat 指令: ng-repeat 指令用来遍历一个数组重复创建当前元素: <ul ng-app="myApp" ng-controller="myAp ...

  3. JSP教程

    http://www.runoob.com/jsp/jsp-tutorial.html

  4. Code Forces 652A Gabriel and Caterpillar

    A. Gabriel and Caterpillar time limit per test 1 second memory limit per test 256 megabytes input st ...

  5. POI官网中的例子

    官方指南中的例子: http://poi.apache.org/spreadsheet/quick-guide.html#New+Sheet 这一节 Workbook wb = new HSSFWor ...

  6. oracle goldengate技术架构-简单试验(全)

    一  GoldenGate简介 Oracle Golden Gate软件是一种基于日志的结构化数据复制备份软件,它通过解析源 数据库在线日志或归档日志获得数据的增量变化,再将这些变化应用到目标数据库, ...

  7. 【asm】64位编译32位汇编需要注意的

    汇编语言在32位和64位下有区别    32位的汇编在代码前增加.code32    as可以通过--32指定生成32位汇编 在64位系统下ld链接生成32位程序:    ld: i386 archi ...

  8. 设计模式之——浅谈strategy模式(策略模式)

    strategy模式,即策略模式.个人觉得吧,策略模式更多的是一种思维方式. 首先我们要知道,为什么需要策略模式.举个例子,比如用程序输出今天下午去玩什么. PlayGame 玩游戏 package ...

  9. installEventFilter可以安装到任何QObject的子类,并不仅仅是UI组件。事件过滤器和安装过滤器的组件必须在同一线程,在它们分属在不同线程时,事件过滤器也是不起作用的

    Qt的事件知识点: ①事件对象创建完毕后,Qt 将这个事件对象传递给 QObject 的 event() 函数.event() 函数并不直接处理事件,而是将这些事件对象按照它们不同的类型,分发给不同的 ...

  10. Python开发【笔记】: __get__和__getattr__和__getattribute__区别

    引言: 1.object.__getattr__(self, name) 当一般位置找不到attribute的时候,会调用getattr,返回一个值或AttributeError异常. 2.objec ...