HDU 1176(類似數字三角形的題,很經典,值得仔細理解的dp思維)
阿新 • • 發佈:2018-06-08
ron 接下來 開始 bre 就是 變形 style 的人 %d
為了使問題簡化,假設在接下來的一段時間裏,餡餅都掉落在0-10這11個位置。開始時gameboy站在5這個位置,因此在第一秒,他只能接到4,5,6這三個位置中其中一個位置上的餡餅。問gameboy最多可能接到多少個餡餅?(假設他的背包可以容納無窮多個餡餅)
提示:本題的輸入數據量比較大,建議用scanf讀入,用cin可能會超時。
Sample Input
6
5 1
4 1
6 1
7 2
7 2
8 3
0
第五秒:0,1,2,3,4,5,6,7,8,9,10
第六秒:0,1,2,3,4,5,6,7,8,9,10
非常的類似數字三角形,回顧一下數字三角形:從頂向下走(只能向下或者左下),怎麽走使得走過的路權值之和最大
回到這個問題,這個問題的權值就是某個時刻某個位置餡餅的個數
dp[i][j]:第i秒j位置餡餅的個數
是不是非常非常類似數字三角形?
每次移動的話只要三個選擇:向左一個單位,向右一個單位,不動
所以狀態轉移方程:
dp[i][j]=max(dp[i+1][j],max(dp[i+1][j-1],dp[i+1][j+1]))+dp[i][j];
跟數字三角形一樣,倒推
註意初始化:
dp數組初始化為0,表示一開始所有時刻,所有位置餡餅個數為0
每個時刻每個位置餡餅的個數要隨著輸入寫好
找到時刻的最大值,這樣從時刻最大值倒數循環
代碼如下:
題目鏈接:
http://acm.hdu.edu.cn/showproblem.php?pid=1176
免費餡餅
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 60927 Accepted Submission(s): 21380
為了使問題簡化,假設在接下來的一段時間裏,餡餅都掉落在0-10這11個位置。開始時gameboy站在5這個位置,因此在第一秒,他只能接到4,5,6這三個位置中其中一個位置上的餡餅。問gameboy最多可能接到多少個餡餅?(假設他的背包可以容納無窮多個餡餅)
Input 輸入數據有多組。每組數據的第一行為以正整數n(0<n<100000),表示有n個餡餅掉在這條小徑上。在結下來的n行中,每行有兩個整數x,T(0<T<100000),表示在第T秒有一個餡餅掉在x點上。同一秒鐘在同一點上可能掉下多個餡餅。n=0時輸入結束。
Output 每一組輸入數據對應一行輸出。輸出一個整數m,表示gameboy最多可能接到m個餡餅。
提示:本題的輸入數據量比較大,建議用scanf讀入,用cin可能會超時。
Sample Output 4 分析: 一開始真的不知道是個數字三角形的變形題,思考了很久,最後看了別人的題解。。。。。。。 分析: 一個人站在5的位置 第一秒能到的位置:4,5,6 第二秒能到的位置:3,4,5,6,7 第三秒能到達的位置:2,3,4,5,6,7,8 依次類推: 第一秒: 4,5,6 第二秒: 3,4,5,6,7 第三秒: 2,3,4,5,6,7,8 第四秒: 1,2,3,4,5,6,7,8,9
#include<bits/stdc++.h> using namespace std; #define max_v 100005 int dp[max_v][20]; int main() { int n; while(~scanf("%d",&n)) { if(n==0) break; memset(dp,0,sizeof(dp)); int t=-1; for(int i=0;i<n;i++) { int x,y; scanf("%d %d",&x,&y); dp[y][x]++; if(y>t) t=y; } for(int i=t-1;i>=0;i--) { for(int j=10;j>=0;j--) { dp[i][j]=max(dp[i+1][j],max(dp[i+1][j-1],dp[i+1][j+1]))+dp[i][j]; } } printf("%d\n",dp[0][5]); } return 0; }
HDU 1176(類似數字三角形的題,很經典,值得仔細理解的dp思維)