poj1661 (DP)
Posted frankchen831x
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 ",dp[n][0]); 48 } 49 return 0; 50 }
以上是关于poj1661 (DP)的主要内容,如果未能解决你的问题,请参考以下文章