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呢?

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

  • 相关阅读:
    TensorFlow 基础 (04)
    面向对象编程思想的介绍
    B2B、B2C、C2C、O2O的概念
    为什么我们需要域
    如何在阿里云服务器上搭建wordpress个人网站
    Ghost手动备份、还原系统详细图文教程
    IE浏览器下载文件保存时提示:“你没有权限在此位置中保存文件”解决办法
    电脑经常自动重启的一些解决办法
    ERP系统到底能做什么?
    SQL实用技巧:如何分割字符串
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/12356169.html
Copyright © 2011-2022 走看看