题意:老鼠从某点开始下落,1m/s,它跑动的速度也是1米/秒,其中有很多平台,当Jimmy跑到平台的边缘时,开始继续下落。Jimmy每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束。
思路:DP,开个二维数组dp[1010][2]保存走左右边缘的最小值~
题目连接:http://poj.org/problem?id=1661
View Code
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <string> 6 #include <algorithm> 7 #include <iostream> 8 using namespace std; 9 const int N=1010; 10 const int inf=1<<30; 11 12 typedef struct In{ 13 int l,r,h; 14 }In; 15 In a[N]; 16 int dp[N][2]; 17 18 int cmp(In a,In b){ 19 return a.h>b.h; 20 } 21 22 int main(){ 23 24 // freopen("data.in","r",stdin); 25 // freopen("data.out","w",stdout); 26 27 int t,N,Y,X,MAX; 28 scanf("%d",&t); 29 while(t--){ 30 scanf("%d%d%d%d",&N,&X,&Y,&MAX); 31 a[0].l=a[0].r=X; 32 a[0].h=Y; 33 for(int i=1;i<=N;i++) 34 scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].h); 35 sort(a+1,a+N+1,cmp); 36 memset(dp,0x0f0f0f0f,sizeof(dp)); 37 dp[0][0]=dp[0][1]=0; 38 for(int i=0;i<=N;i++){ 39 for(int j=i+1;j<=N;j++){ 40 if(a[i].h-a[j].h<=MAX){ 41 if(a[j].l<=a[i].l&&a[j].r>=a[i].l){ 42 dp[j][0]=min(dp[j][0],dp[i][0]+a[i].l-a[j].l+a[i].h-a[j].h); 43 dp[j][1]=min(dp[j][1],dp[i][0]+a[j].r-a[i].l+a[i].h-a[j].h); 44 break; 45 } 46 } 47 } 48 for(int j=i+1;j<=N;j++){ 49 if(a[i].h-a[j].h<=MAX){ 50 if(a[j].l<=a[i].r&&a[j].r>=a[i].r){ 51 dp[j][0]=min(dp[j][0],dp[i][1]+a[i].r-a[j].l+a[i].h-a[j].h); 52 dp[j][1]=min(dp[j][1],dp[i][1]+a[j].r-a[i].r+a[i].h-a[j].h); 53 break; 54 } 55 } 56 } 57 } 58 int MIN=inf; 59 for(int i=N;i>=0;i--){ 60 if(a[i].h>MAX) break; 61 bool flag=false; 62 for(int j=i+1;j<=N;j++){ 63 if(a[j].l<=a[i].l&&a[j].r>=a[i].l){ 64 flag=true; 65 break; 66 } 67 } 68 if(!flag) MIN=min(MIN,dp[i][0]+a[i].h); 69 flag=false; 70 for(int j=i+1;j<=N;j++){ 71 if(a[j].l<=a[i].r&&a[j].r>=a[i].r){ 72 flag=true; 73 break; 74 } 75 } 76 if(!flag) MIN=min(MIN,dp[i][1]+a[i].h); 77 } 78 printf("%d\n",MIN); 79 } 80 return 0; 81 }