您的位置:首页 > 其它

ZOJ3541与时间相关的区间dp+记录路径

2017-07-29 20:15 387 查看

与时间相关的区间dp+记录路径

题意:

一个英雄深陷龙穴,现在有一个门,不过想把门打开需要把门上的按钮全部在同一时间都是按下状态,按钮排成一排:每一个按钮都有两个属性:

按下的状态能维持ai 个单位时间

按钮之间有距离,具体就是离第一个按钮的距离

问:英雄是否能使得全部 的按钮在同一时间都保持被按下的状态?如果可以请输出按按钮的顺序,如果不能输出一个字符串。

思路:

先普及一个知识:一个区间如果想遍历完,并且是时间最短,自然就是只能从两端开始,这样会把时间最短。

对于本题来说:遍历所有按钮的时间越短就会使得被按下按钮维持的时间更充裕

所以:对于一排按钮有两种可能

从左到右按下

从右到左按下

定义:dp[i][j][0] 表示从第i到第j的所有按钮被按下的最短时间,第三维0表示第i到第j是从做到右

dp[i][j][1] 表示从第i到第j的所有按钮被按下的最短时间,第三维1表示第i到第j是从右到左。

那么只需要遍历区间就行了,对于每一次判断从右还是从左只需单独比较就行了。

不过这道题最有意思还有一点就是:保存路径,其巧妙程度值得推敲

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 1005;
const int INF = 0x3f3f3f3f;

int n;
int a[maxn],b[maxn];
int dp[maxn][maxn][2];
int path[maxn][maxn][2];

int main(int argc, char const *argv[])
{
//freopen("in.txt","r",stdin);

while(scanf("%d",&n) != EOF) {
memset(dp,0,sizeof(dp));
memset(path,0,sizeof(path));
for(int i = 1;i <= n; i++) {
scanf("%d",&a[i]);
}
for(int j = 1;j <= n; j++) {
scanf("%d",&b[j]);
}
for(int l = 2;l <= n; l++) {
for(int i = 1;i+l-1 <= n; i++) {
int j = i + l - 1;
/*从左向右*/
int temp1 = dp[i+1][j][0] + b[i+1] - b[i];
int temp2 = dp[i+1][j][1] + b[j] - b[i];
if(temp1 <= temp2) {
dp[i][j][0] = temp1;
path[i][j][0] = 0;      /*定义为i到j从左走之后下一次走从左向右为0*/
}
else {
dp[i][j][0] = temp2;
path[i][j][0] = 1;      /*定义为i到j从左走之后下一次走从右向左为1*/
}
if(a[i] <= dp[i][j][0])     /*若低于i自动上升的是时间则为不可达*/
dp[i][j][0] = INF;
/*从右往左*/
temp1 = dp[i][j-1][1] + b[j] - b[j-1];
temp2 = dp[i][j-1][0] + b[j] - b[i];
if(temp1 >= temp2) {
dp[i][j][1] = temp2;
path[i][j][1] = 0;
}
else {
dp[i][j][1]
e29c
= temp1;
path[i][j][1] = 1;
}
if(a[j] <= dp[i][j][1])
dp[i][j][1] = INF;
}
}
int l,r,temp;
if(dp[1]
[0] < INF) {
temp = path[1]
[0];
l = 2,r = n;
printf("1");
}
else if(dp[1]
[1] < INF) {
temp = path[1]
[1];
l = 1,r = n - 1;
printf("%d",n);
}
else {
printf("Mission Impossible\n");
continue;
}
while(l <= r) {
if(temp == 0) {
temp = path[l][r][0];
printf(" %d",l++);
}
else {
temp = path[l][r][1];
printf(" %d",r--);
}
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp zoj