zoukankan      html  css  js  c++  java
  • codeforces 1579G Codeforces Round #744 (Div. 3)

    题意:

    按顺序给定n条线段,从0开始,可以正放也可以反放(+x,-x),问n条放完之后最小覆盖区间长度。

    思路:

    很容易可以想到对于一个左端点找一个最左的右端点,但是如果是确定的左右坐标,我们会无法知道当前的位置,然后无法进行转移。

    又考虑到左右端点和当前位置的具体坐标其实不需要知道,我们只需要一个距离也就是相对长度。

    所以不妨把左右端点以及当前位置进行相对位置的记录。

    那么原本的dp[i][j]表示第i条的左端点的最优右端点变成了dp[i][j]表示第i条距离左端点的相对位置为j时右端点的最优解。

    当j<a[i]时,说明此时-a[i]会移动左端点,那么相对距离变成0,移左相当于移右。

    其余情况正常转移。

    而且值域必定在2000以内。

    下附代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int INF=0X3f3f3f3f;
    int dp[10005][2005];
    int main(){
        int T;
        scanf("%d",&T);
        while (T--){
            int n;
            scanf("%d",&n);
            for (int i=0; i<=n; i++){
                for (int j=0; j<=2000; j++){
                    dp[i][j]=INF;
                }
            }
            dp[0][0]=0;
            for (int i=1; i<=n; i++){
                int x;
                scanf("%d",&x);
                for (int j=0; j<=2000; j++){
                    if (dp[i-1][j]!=INF){
                        if (j<x){
                            dp[i][0]=min(dp[i][0],dp[i-1][j]+(x-j));
                        }
                        else {
                            dp[i][j-x]=min(dp[i][j-x],dp[i-1][j]);
                        }
                        if (j+x<=2000) dp[i][j+x]=min(dp[i][j+x],max(dp[i-1][j],j+x));
                    }
                }
            }
            int res=INF;
            for (int i=0; i<=2000; i++){
                res=min(res,dp[n][i]);
            }
            printf("%d
    ",res);
        }
    }
    /*10
    5 6 7 3 3 1 3 5 4 6
    */
    View Code
  • 相关阅读:
    webkit v8 chromium blink chrome 的关系
    webkit 系列
    工具使用过程中遇到问题
    ElasticSearch实战笔记
    办理北京市居住证需要哪些资料
    办理北京市居住证需要哪些资料
    MongoDB 笔记
    Javascript问题集锦
    sqlserver2016 management tool v18
    PostMan测试Web Service
  • 原文地址:https://www.cnblogs.com/i-caigou-TT/p/15354367.html
Copyright © 2011-2022 走看看