首页 > 其他分享 >CodeForces - 797F Mice and Hole

CodeForces - 797F Mice and Hole

时间:2022-11-19 16:33:41浏览次数:52  
标签:老鼠 5005 sum 797F CodeForces Mice ll dp define

题意:有n只老鼠,m个洞。n只老鼠的坐标分别为x[i],m个洞坐标分别为p[i],能装c[i]只老鼠。现在老鼠要往洞里跑,求所有老鼠跑的最短路线之和。

解:一开始准备拿老鼠转移,然后复杂度爆了,于是进行一些观察。先本能地给洞和老鼠排个序,然后发现跑的路最短的情况下,一个洞里的老鼠肯定是连续的。嗯怎么有点像我出的那个题。考虑设dp[i][j]为前i个洞里装了前j只老鼠,先不管能不能装下,那么转移的时候就是枚举新出现的洞里装几只老鼠,转移方程为:

dp[i][j]=min(dp[i-1][k]+sum[k+1...j]),其中[k+1...j]要小于等于洞的容量。

这样是O(n2m)的。因为每次转移都是取连续的一段区间,可以用单调队列优化一下。注意把不可行的方案设为inf。

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxx 1005
#define maxn 25
#define maxm 205
#define ll long long
#define inf 1000000009
#define mod 2520
ll x[5005];
vector<pair<ll,ll> > v;
ll dp[5005][5005]={0};
ll sum[5005]={0};
int q[5005]={0};
signed main() {
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",&x[i]);
    }
    ll res=0;
    for(int i=1;i<=m;i++){
        ll p,c;
        scanf("%lld%lld",&p,&c);
        v.push_back(make_pair(p,c));
        res+=c;
    }
    if(res<n){
        printf("-1\n");
        return 0;
    }
    sort(x+1,x+n+1);
    sort(v.begin(),v.end());
    for(int i=1;i<=n;i++){
        dp[0][i]=1e18;
    }
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            sum[j]=sum[j-1]+abs(v[i-1].first-x[j]);
        }
        int head=1,tail=0;
        for(int j=0;j<=n;j++){
            while(head<=tail&&q[head]<j-v[i-1].second) head++;
            while(head<=tail&&dp[i-1][q[tail]]-sum[q[tail]]>=dp[i-1][j]-sum[j]) tail--;
            q[++tail]=j;
            dp[i][j]=dp[i-1][q[head]]+sum[j]-sum[q[head]];
        }
    }
    printf("%lld\n",dp[m][n]);
    return 0;
}
View Code

 

标签:老鼠,5005,sum,797F,CodeForces,Mice,ll,dp,define
From: https://www.cnblogs.com/capterlliar/p/16906352.html

相关文章

  • Codeforces Round #834 (Div. 3) A-G
    比赛链接A题目知识点:模拟。确定开头字母,然后循环比较即可。时间复杂度\(O(n)\)空间复杂度\(O(n)\)题解#include<bits/stdc++.h>#definelllonglongusingn......
  • Codeforces Round #834 (Div. 3) G
    G.RestorethePermutation对于一个序列要是我们从数小a[i]的开始每次给这个a[i]选一个最接近她的一个小的显然我们这样是最合法的但是怎么保证字典序最小呢显然我......
  • 题解 Codeforces Round #834 (Div. 3) ABCDEF
    A.Yes-Yes?problem判断给定的字符串是否为无穷个YesYesYes拼接组成的字符串的连续子串。\(|S|\leq50\)。solution暴力。具体地,判断\(S,Ye+S,Y+S\)是否有一个是......
  • Codeforces Round #834 (Div. 3)
    ABC略。D.MakeItRound问题可以看成凑出尽可能多的\(10\)作为因子。注意到\(10\)的因子只有\(1,2,5,10\)。首先,\(n\)自己已经凑出来的\(10\)没必要拆开,并......
  • Codeforces Round #829 A+B+C+D 题解
    A.TheUltimateSquare题意询问\(T\)次,给定\(n\)块木板,第\(i\)块为\(1\times\lceil\fraci2\rceil\)大小,求能拼出的最大正方形边长数据范围:\(1\len\le10^9,1......
  • CodeForces - 15D Map
    题意:要在一片n*m的地上盖一个a*b的房子。这片地参差不齐,如果选定一个a*b的区域盖房子的话,需要把这片地铲地和最低点一样平,消耗的代价为铲掉高度之和。按代价大小求所有不重......
  • Codeforces Round #673 (Div. 2) Problem A
    今天的题。本来打算把比赛坚持打完的,但是因为生病了,还是早点睡吧,把第一题摸了。题面如下:BTheroisapowerfulmagician.Hehasgotnpilesofcandies,thei-thpile......
  • Codeforces Round #672 (Div. 2) ProblemB
    9月25日的打卡。为什么又过了零点?因为和朋友去摸鱼了。今天讲一下昨晚比赛的第二题。题面如下:Danikurgentlyneedsrockandlever!Obviously,theeasiestwaytoge......
  • Codeforces Round #672 (Div. 2) Problem A
    今日份的题目。(指9月24日,因为比赛从晚上10点半持续到12点半)问题A是水题,题面如下(大半夜了,就不翻译了,赶着睡觉)(其他题目明天再发)Wheatleydecidedtotrytomakeatestcha......
  • codeforces 2000左右dp题目练习
    栾巨的dp题单,刷完他要v我500可以提升dp水平。1.YaroslavandTwoStrings白给题,令\(f_{i,0/1,0/1}\)表示前\(i\)位,有无小于,有无大于,根据每位的字符转移即可。2.To......