poj 1088 滑雪-----DP 動態規劃
阿新 • • 發佈:2019-01-27
滑雪
一個人可以從某個點滑向上下左右相鄰四個點之一,當且僅當高度減小。在上面的例子中,一條可滑行的滑坡為24-17-16-1。當然25-24-23-...-3-2-1更長。事實上,這是最長的一條。
輸入的第一行表示區域的行數R和列數C(1 <= R,C <= 100)。下面是R行,每行有C個整數,代表高度h,0<=h<=10000。
Time Limit:1000MS | Memory Limit:65536K |
Total Submissions:57209 | Accepted:20771 |
Description
Michael喜歡滑雪百這並不奇怪, 因為滑雪的確很刺激。可是為了獲得速度,滑的區域必須向下傾斜,而且當你滑到坡底,你不得不再次走上坡或者等待升降機來載你。Michael想知道載一個區域中最長底滑坡。區域由一個二維陣列給出。陣列的每個數字代表點的高度。下面是一個例子1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
一個人可以從某個點滑向上下左右相鄰四個點之一,當且僅當高度減小。在上面的例子中,一條可滑行的滑坡為24-17-16-1。當然25-24-23-...-3-2-1更長。事實上,這是最長的一條。
Input
Output
輸出最長區域的長度。Sample Input
5 5 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
Sample Output
25
中文的,題目意思就不寫了。 - -
我的 解題思路 :用dp[i][j]的值記錄 map[i][j]點 能走的最長的值。 如果一個點周圍都比自己高 或邊界,即為最低點 dp[i][j]即為1,然後其他點根據周圍低的點dp[i][j] 值不斷更新最大值。直到所有點的dp[i][j]都確定。
程式碼:
//Memory: 296 KB Time: 500 MS //Language: C++ Result: Accepted #include<stdio.h> #include<string.h> int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; //四個方向 int map[105][105],dp[105][105],vir[105][105]; //map構圖,dp記錄每一個點的最長值,vir標記 int main() { // freopen("in.txt","r",stdin); int h,w,i,j,count; while(scanf("%d%d",&h,&w)!=EOF) { memset(vir,0,sizeof(vir)); count=0; for(i=0;i<h;i++) for(j=0;j<w;j++) { scanf("%d",&map[i][j]); dp[i][j]=0; } while(1) { for(i=0;i<h;i++) { for(j=0;j<w;j++) { int big=0,temp=0; //temp 記錄周圍是否都是確定了最大值的點 for(int k=0;k<4;k++) { if(vir[i][j]) continue; int tx=i+dir[k][0],ty=j+dir[k][1]; if(tx<0||tx>=h||ty<0||ty>=w|| map[tx][ty]>=map[i][j]) { big++; //big的值可以理解為 周圍 比這個點高或邊界 temp++; continue; } if(map[tx][ty]<map[i][j] && vir[tx][ty]) { temp++; if(dp[tx][ty]+1>dp[i][j]) //狀態轉移 總是取較大值 dp[i][j]=dp[tx][ty]+1; } } if(big==4) dp[i][j]=1; //big為4說明是最低點 if(temp==4) //如果周圍的點都已經確認,這個點的值也不在變化,標記,計數. { vir[i][j]=1; count++; if(count==h*w) break; } } if(count==h*w) break; } if(count==h*w) break; } int max=0; for(i=0;i<h;i++) //找出最大值 for(j=0;j<w;j++) if(dp[i][j]>max) max=dp[i][j]; printf("%d\n",max); } return 0; }