zoukankan      html  css  js  c++  java
  • The Last Puzzle ZOJ

    题目链接
    本题也是区间dp,贪心可证,每一次出发必定是从端点,否则必然有重复,不会是最小值,那我们可以设dpi,j,0/1,0代表从左端点出发,1代表从右端点,因为每次都是从端点出发,状态方程为
    dpi,j,0=min(dpi+1,j,0+d[i+1]-d[i], dpi+1,j,1+dp[j]-dp[i])分别表示from i to i+1 to j, from i to j to i+1
    dpi,j,1=min(dpi,j-1,1+d[j]-d[j-1], dpi,j-1,0+dp[j]-dp[i])分别表示from j to j-1 to i, from j to i to j-1

    #include<bits/stdc++.h>
    using namespace std;
    #define lowbit(x) ((x)&(-x))
    typedef long long LL;
    typedef pair<int,int> pii;
    
    const int maxn = 205;
    const int INF = 0x3f3f3f3f;
    int dp[maxn][maxn][2], d[maxn], t[maxn], mov[maxn][maxn][2];
    
    void run_case() {
        int n;
        while(cin >> n) {
            for(int i = 1; i <= n; ++i) cin >> t[i];
            for(int i = 1; i <= n; ++i) cin >> d[i];
            memset(dp, 0, sizeof(dp));
            for(int i = n-1; i >= 1; --i) {
                for(int j = i+1; j <= n; ++j) {
                    
                    if(dp[i+1][j][0] + d[i+1] - d[i] < dp[i+1][j][1] + d[j] - d[i]) {
                        dp[i][j][0] = dp[i+1][j][0] + d[i+1] - d[i];
                        mov[i][j][0] = 0; // from i to i+1
                    } else {
                        dp[i][j][0] = dp[i+1][j][1] + d[j] - d[i];
                        mov[i][j][0] = 1; // from i to j
                    }
                    if(dp[i][j][0] >= t[i]) {
                        dp[i][j][0] = INF;
                    }
                    // calculate dp[i][j][1]
                    if(dp[i][j-1][0] + d[j] - d[i] < dp[i][j-1][1] + d[j] - d[j-1]) {
                        dp[i][j][1] = dp[i][j-1][0] + d[j] - d[i];
                        mov[i][j][1] = 0; // from j to i
                    } else {
                        dp[i][j][1] = dp[i][j-1][1] + d[j] - d[j-1];
                        mov[i][j][1] = 1; // from j to j-1
                    }
                    if(dp[i][j][1] >= t[j]) {
                        dp[i][j][1] = INF;
                    }
                }
            }
            int l=0, r=-1, flag;
            if(dp[1][n][0] < INF) {
                l = 2, r = n;
                flag = mov[1][n][0];
                cout << "1";
            } else if(dp[1][n][1] < INF) {
                l = 1, r = n-1;
                flag = mov[1][n][1];
                cout << n;
            } else {
                cout << "Mission Impossible";
            }
            while(l <= r) {
                if(flag) {
                    cout << " " << r;
                    flag = mov[l][r][1];
                    r--;
                } else {
                    cout << " " << l;
                    flag = mov[l][r][0];
                    l++;
                }
            }
            cout << "
    ";
        }
    }
    
    int main() {
        ios::sync_with_stdio(false), cin.tie(0);
        cout.flags(ios::fixed);cout.precision(10);
        //int t; cin >> t;
        run_case();
        cout.flush();
        return 0;
    }
    

    何时区间dp呢?

    数据范围一定
    需要维护区间状态,不同区间选择造成的影响不同,石子合并,杀狼等

  • 相关阅读:
    libxml2.7.8 c++ 解析xml文件
    Head First设计模式-模板方法模式
    嵌入式开发之工具移植--openssl移植
    嵌入式开发之工具移植--wpa_suppliant工具的移植和使用
    linux下嵌入式wifi开发工具移植
    IOS面试题(英文)
    机器学习学习笔记 PRML Chapter 2.0 : Prerequisite 1
    机器学习学习笔记 PRML Chapter 2.0 : Prerequisite 2 -Singular Value Decomposition (SVD)
    CCJ PRML Study Note
    CCJ PRML Study Note
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/12356169.html
Copyright © 2011-2022 走看看