zoj3541(区间DP)

版权声明:如果看得起就随便拿去用吧QWQ https://blog.csdn.net/qkoqhh/article/details/83717077

题意:给定一个灯序列和他们的坐标,第i个灯在点亮之后ti秒后会熄灭,要求一个序列使得依次点亮序列上的灯会使得有一个时刻灯会亮着

这个题还是有点技巧的。。首先如果确定好序列之后,只要考虑第i个灯的ti到和它点亮后面所有灯的时间的大小关系就可以了。。

然后考虑如果从中间开始点亮,那么无论下次从左走开始从右走必定会再次经过这个点,那么这时再次点亮他这个灯就会获得更加持久的持续时间,那么第一个点亮就失去了意义。这样,可以知道,我们必定从最左边的灯或者最右边的灯开始点亮,显然这个结论也可以适用在一个区间内,因此我们就可以考虑做区间DP了。。

设d[i][j][k]表示将区间[i,j]点亮所需要的时间,k==0表示从左端点开始点亮,k==1表示从右端点开始点亮

然后将端点点亮之后考虑剩下的区间从哪端开始点亮即可。。

/**
 *        ┏┓    ┏┓
 *        ┏┛┗━━━━━━━┛┗━━━┓
 *        ┃       ┃  
 *        ┃   ━    ┃
 *        ┃ >   < ┃
 *        ┃       ┃
 *        ┃... ⌒ ...  ┃
 *        ┃       ┃
 *        ┗━┓   ┏━┛
 *          ┃   ┃ Code is far away from bug with the animal protecting          
 *          ┃   ┃   神兽保佑,代码无bug
 *          ┃   ┃           
 *          ┃   ┃        
 *          ┃   ┃
 *          ┃   ┃           
 *          ┃   ┗━━━┓
 *          ┃       ┣┓
 *          ┃       ┏┛
 *          ┗┓┓┏━┳┓┏┛
 *           ┃┫┫ ┃┫┫
 *           ┗┻┛ ┗┻┛
 */
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-8
#define succ(x) (1LL<<(x))
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define NM 205
#define nm 10005
#define pi 3.1415926535897931
using namespace std;
const ll inf=1e9+7;
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}







int n,a[NM],b[NM];
ll d[NM][NM][2];
bool v[NM][NM];

void dfs(int x,int y){
    if(v[x][y])return;v[x][y]++;
    if(x==y){d[x][y][0]=d[x][y][1]=0;return;}
    dfs(x+1,y);
    dfs(x,y-1);
    d[x][y][0]=min(b[x+1]-b[x]+d[x+1][y][0],b[y]-b[x]+d[x+1][y][1]);
    d[x][y][1]=min(b[y]-b[y-1]+d[x][y-1][1],b[y]-b[x]+d[x][y-1][0]);
    if(d[x][y][0]>=a[x])d[x][y][0]=inf;
    if(d[x][y][1]>=a[y])d[x][y][1]=inf;
}

void _dfs(int x,int y,int t){
    if(x==y){printf("%d\n",x);return;}
    if(t){
	printf("%d ",y);
	if(d[x][y][t]==b[y]-b[y-1]+d[x][y-1][1])_dfs(x,y-1,1);
	else _dfs(x,y-1,0);
    }else{
	printf("%d ",x);
	if(d[x][y][t]==b[x+1]-b[x]+d[x+1][y][0])_dfs(x+1,y,0);
	else _dfs(x+1,y,1);
    }
}

int main(){
    //freopen("data.in","r",stdin);
    while(~scanf("%d",&n)){
	mem(d);mem(v);
	inc(i,1,n)a[i]=read();
	inc(i,1,n)b[i]=read();
	dfs(1,n);
	if(d[1][n][1]<inf)_dfs(1,n,1);
	else if(d[1][n][0]<inf)_dfs(1,n,0);
	else printf("Mission Impossible\n");
    }
    return 0;
}

The Last Puzzle


Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge




There is one last gate between the hero and the dragon. But opening the gate isn't an easy task.

There were n buttons list in a straight line in front of the gate and each with an integer on it. Like other puzzles the hero had solved before, if all buttons had been pressed down in any moment, the gate would open. So, in order to solve the puzzle, the hero must press all the button one by one.

 After some trials, the hero found that those buttons he had pressed down would pop up after a while before he could press all the buttons down. He soon realized that the integer on the button is the time when the button would automatic pop up after pressing it, in units of second. And he measured the distance between every button and the first button, in units of maximum distance the hero could reach per second. Even with this information, the hero could not figure out in what order he should press the buttons. So you talent programmers, are assigned to help him solve the puzzle.

To make the puzzle easier, assuming that the hero always took integral seconds to go from one button to another button and he took no time turnning around or pressing a button down. And the hero could begin from any button.

Input

The input file would contain multiple cases. Each case contains three lines. Process to the end of file.

The first line contains a single integer n(1 ≤ n ≤200), the number of buttons.

The second line contains n integers T1, T2, ..., Tn, where Ti(1 ≤ Ti ≤ 1,000,000) is the time the ith button would automatic pop up after pressing it, in units of second.

The third line contains n integers D1, D2, ..., Dn, where Di(1 ≤ Di ≤ 1,000,000) is the time hero needed to go between the ith button and the first button, in units of second. The sequence will be in ascending order and the first element is always 0.

Output

Output a single line containing n integers which is the sequence of button to press by the hero. If there are multiply sequences, anyone will do. If there is no way for the hero to solve the puzzle, just output "Mission Impossible"(without quote) in a single line.

Sample Input

2
4 3
0 3
2
3 3
0 3
4
5 200 1 2
0 1 2 3

Sample Output

1 2
Mission Impossible
1 2 4 3

Hint

In the second sample, no matter which button the hero pressed first, the button would always pop up before he press the other button. So there is no way to make all the button pressed down.


Author: WANG, Yelei
Contest: The 2011 ACM-ICPC Asia Dalian Regional Contest

Submit    Status

猜你喜欢

转载自blog.csdn.net/qkoqhh/article/details/83717077