zoukankan      html  css  js  c++  java
  • CF797F Mice and Holes

    Solution

    有一个非常显然的性质,一个洞最终容纳的一定是一段横坐标连续的老鼠。就是说不可能出现交叉的请况。数学证明也是非常的容易,懒得写了。

    那么就预先将老鼠和洞分别按横坐标排序。这样之后,容易想到 dp 状态 (dp[i][j]) 表示用前 (i) 个洞容纳前 (j) 个老鼠的最小花费。方程也非常好想

    [dp_{i,j}=minlimits_{j-c_ileq k leq j}{dp_{i-1,k}+sum_{k<rleq j} {|P_i-p_r|}} ]

    其中 (P) 是洞的坐标,(p) 是老鼠的坐标,(c) 是洞的容量。特别注意,当前 (i) 个洞填满都不够 (j) 只老鼠时,就不存在方案,(dp_{i,j}=infty)

    (i) 确定时,后面的那个和式可以直接用前缀和优化掉,记为 (S_{i,j})。之后发现 (S_{i,j}) 是与 (k) 无关的变量,所以直接从 (min) 里面提取来。

    [dp_{i,j}=S_{i,j}+minlimits_{j-c_ileq k leq j}{dp_{i-1,k}-S_{i,k}} ]

    枚举一个 (i)(j) 后,后面的 (min) 就只与 (k) 有关了,发现决策集合是连续的若干个区间,所以直接用单调队列优化掉就可以了。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define N 5007
    #define ll long long
    
    inline int read(){
        int x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-') flag=0;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
    
    struct Hole{
        int p,c;
        bool operator <(const Hole X) const{return p<X.p;}
    }t[N];
    
    ll S[N],dp[N][N],V[N];
    int n,m,Q[N],hd=1,tl=0,ret,a[N];
    int main(){
        n=read(),m=read();
        for(int i=1;i<=n;i++) a[i]=read();
        sort(a+1,a+1+n);
        for(int i=1;i<=m;i++)
            t[i].p=read(),t[i].c=read();
        sort(t+1,t+1+m);
        for(int j=1;j<=n;j++) dp[0][j]=(1LL<<60);
        for(int i=1;i<=m;i++){
            ret+=t[i].c;
            for(int j=1;j<=n;j++)
                S[j]=abs(t[i].p-a[j])+S[j-1];
            hd=1,tl=0;
            for(int j=0;j<=n;j++){
                while(hd<=tl&&Q[hd]<j-t[i].c) hd++;
                while(hd<=tl&&dp[i-1][j]-S[j]<=V[tl]) tl--;
                Q[++tl]=j,V[tl]=dp[i-1][j]-S[j];
                if(ret>=j) dp[i][j]=S[j]+V[hd];
                else dp[i][j]=(1LL<<60);
            }
        }
        printf("%lld",(dp[m][n]!=(1LL<<60))? dp[m][n]:-1);
    }
    
  • 相关阅读:
    poj 1475 Pushing Boxes 推箱子(双bfs)
    poj 1806 Frequent values(RMQ 统计次数) 详细讲解
    poj 2846 Repository
    poj Ping pong LA 4329 (树状数组统计数目)
    POJ 1962-Corporative Network (并查集)
    hdu 2217 Visit
    nyoj304 节能
    与R纠缠的两件事——rownames和子集--转载
    七步精通Python机器学习--转载
    win10专业版激活(亲测可用)
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/14191828.html
Copyright © 2011-2022 走看看