zoukankan      html  css  js  c++  java
  • 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;
    				else
    					dp[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);
    		// mainFunction
    		cout << mainFunc() << endl;
    	}
    	return 0;
    }
    

      

    update 2014年3月16日10:36:58

    1. 直接前驱可以预处理得到

  • 相关阅读:
    基于UML和ASP.NET实现三层B/S结构系统开发
    通过避免下列 10 个常见 ASP.NET 缺陷使网站平稳运行(转)
    GOOGLE浏览器(已经可以下载啦)
    虽然很老,但是还是挺有用,而且经常要看。META
    ASP.NET保持用户状态的九种选择
    设计ASP.NET应用程序的七大绝招
    将更智能的 ASP.NET 文件下载体验内置到您的 Web 应用程序中 (MSDN)
    据说是民间最准确的算命法则
    ASP.NET是否是微软继MFC之后最无用的框架?
    宁波单身公寓出租
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3447334.html
Copyright © 2011-2022 走看看