poj1661 (DP)

题目链接:http://poj.org/problem?id=1661

思路:

把初始位置看成左,右端点均为x0,即长度为0,高度为y0的一个平台,按照平台高度从低到高排序。用dp[i][0],dp[i][1]分别表示从第i个平台的左端,右端到地面的最短时间。tmp=get_next(i,0)表示第i个平台左端点下的平台的编号(若为-1表示下方已无平台),同理tmp=get_next(i,1)表示第i个平台右端点下的平台编号。因为求最小值,所以要将dp初始化为inf,因此状态转移方程如下(注意若下降高度大于Max,则不处理,即dp[i][j]等于inf):

               if(tmp>=0){
                    if(a[i].h-a[tmp].h<=Max)
                        dp[i][j]=a[i].h-a[tmp].h+min(dp[tmp][0]+a[i].x[j]-a[tmp].x[0],dp[tmp][1]+a[tmp].x[1]-a[i].x[j]);
                }
                else{
                    if(a[i].h<=Max)
                        dp[i][j]=a[i].h;
                }
详见代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 struct node{
 7     int x[2],h;
 8 }a[1005];
 9 
10 bool cmp(node xx,node yy){
11     return xx.h<yy.h;
12 }
13 
14 int T,n,x0,y0,Max;
15 int dp[1005][2];
16 
17 int get_next(int p,int k){
18     int q=p-1;
19     for(;q>=0;--q)
20         if(a[q].h<a[p].h&&a[p].x[k]>=a[q].x[0]&&a[p].x[k]<=a[q].x[1])
21             break;
22     return q;
23 }
24 
25 int main(){
26     scanf("%d",&T);
27     while(T--){
28         memset(dp,0x3f,sizeof(dp));
29         scanf("%d%d%d%d",&n,&x0,&y0,&Max);
30         a[n].x[0]=a[n].x[1]=x0,a[n].h=y0;
31         for(int i=0;i<n;++i)
32             scanf("%d%d%d",&a[i].x[0],&a[i].x[1],&a[i].h);
33         sort(a,a+n,cmp);
34         int tmp;
35         for(int i=0;i<=n;++i)
36             for(int j=0;j<2;++j){
37                 tmp=get_next(i,j);
38                 if(tmp>=0){
39                     if(a[i].h-a[tmp].h<=Max)
40                         dp[i][j]=a[i].h-a[tmp].h+min(dp[tmp][0]+a[i].x[j]-a[tmp].x[0],dp[tmp][1]+a[tmp].x[1]-a[i].x[j]);
41                 }
42                 else{
43                     if(a[i].h<=Max)
44                         dp[i][j]=a[i].h;
45                 }
46             }
47         printf("%d\n",dp[n][0]);
48     }
49     return 0;
50 }

猜你喜欢

转载自www.cnblogs.com/FrankChen831X/p/10425778.html