POJ 1661 Help Jimmy(递推DP)
生活随笔
收集整理的這篇文章主要介紹了
POJ 1661 Help Jimmy(递推DP)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
思路:
1. 每個板子有左右兩端, dp[i][0], dp[i][1] 分別記錄左右端到地面的時間
2. 從下到上遞推計算, 上一層的板子必然會落到下面的某一層板子上, 或者地面上
?
總結:
1. 計算每個板子的 dp[i][0/1] 僅需考慮該板子的直接前驅即可
2. 動規的思想并不很明顯
3. 代碼中, 兩個板子相對位置的判斷特別精髓
4. 將地面和初始狀態都抽象成一塊板子
?
代碼:
#include <iostream> #include <algorithm> using namespace std;class board { public:int x1, x2, h;board(int _x1, int _x2, int _h):x1(_x1), x2(_x2), h(_h){}board() {board(-1,-1,-1);}bool operator <(const board & other) const {return this->h < other.h;} };const int INF = 0X3F3F3F3F; const int MAXN = 1010; int t, N, X, Y, H, MAX; board boards[MAXN]; int dp[MAXN][2];int mainFunc() {for(int i = 0; i <= N+1; i ++) {for(int j = i-1; j >= 0; j --) {if(boards[i].x1 >= boards[j].x1 && boards[i].x1 <= boards[j].x2) { // i 的左端可以掉落到 j 上int h = boards[i].h - boards[j].h;if(h > MAX) dp[i][0] = INF;else if (j == 0) dp[i][0] = h;else dp[i][0] = min(dp[j][0]+boards[i].x1-boards[j].x1, dp[j][1]+boards[j].x2-boards[i].x1) + h;break;}}for(int j = i-1; j >= 0; j --) {if(boards[i].x2 >= boards[j].x1 && boards[i].x2 <= boards[j].x2) { // i 的右端可以掉到 j 上int h = boards[i].h - boards[j].h;if(h > MAX) dp[i][1] = INF;else if(j == 0) dp[i][1] = h;elsedp[i][1] = min(dp[j][0]+boards[i].x2-boards[j].x1, dp[j][1]+boards[j].x2-boards[i].x2) + h;break;}}}return dp[N+1][1]; }int main() {freopen("E:\\Copy\\ACM\\poj\\1661\\in.txt", "r", stdin);cin >> t;while(t-- >= 1) {cin >> N >> X >> H >> MAX;for(int i = 0; i < N; i ++) {cin >> boards[i].x1 >> boards[i].x2 >> boards[i].h;}boards[N].x1 = -20010, boards[N].x2 = 20010, boards[N].h = 0;boards[N+1].x1 = X, boards[N+1].x2 = X, boards[N+1].h = H;sort(boards, boards+N+2);// mainFunctioncout << mainFunc() << endl;}return 0; }
update 2014年3月16日10:36:58
1. 直接前驅可以預處理得到
轉載于:https://www.cnblogs.com/xinsheng/p/3447334.html
總結
以上是生活随笔為你收集整理的POJ 1661 Help Jimmy(递推DP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于在VS 2013 Reshaper
- 下一篇: OpenJudge计算概论-找和为K的两