• CF883D Packmen Strike Back


    CF883D Packmen Strike Back

    (problem:)

    给出一个长度为N的序列,序列上每个位置或者是豆,或者是吃豆人,或者什么都没有
    现在要求给每个吃豆人定向(向左吃或向右吃),定向后吃豆人会一直朝这个方向走直到尽头并吃掉沿途的所有豆
    现在要求在保证尽量多的豆被吃的情况下,最小化达到这个数量所需要的时间(不一定走到尽头)

    (data) (range:)

    (N<=10^6)

    (solution:)

    此题也很妙啊
    考虑如果只有一个人,那么他要么往左要么往右,判断下就行了
    如果有至少两个人,那么所有豆子都可以被吃完,问题变为如何求吃完所有豆子所需要的最少时间
    这个时间本身并不好求
    容易发现答案具有单调性,于是我们考虑二分答案+验证
    如何验证呢?
    (f_i)表示从左往右前第i个人能够吃到的最靠右的豆子的位置(注意中间不能遗漏)
    那么考虑转移,有三种

    • 第i个人向右走
    • 第i个人向左走
    • 第i个人向左走,第i-1个人向右走

    分类讨论即可

    (space) (time) (complexity)

    (time:O(n))
    (space:O(n))

    (code:)

    #include<bits/stdc++.h>
    #define pb push_back
    using namespace std;
    const int N=1e6+5;
    int n,s[N],f[N];
    char ch[N];
    vector<int>p;
    inline bool ok(int l,int r){return l>r?1:(s[r]-s[l-1]==0);}
    inline int sum(int l,int r){return l>r?0:s[r]-s[l-1];}
    inline bool ck(int x)
    {
    	fill(f,f+n+1,0);
    	for(int i=1;i<=p.size();++i)
    	{
    		int pos=p[i-1];
    		if(ok(f[i-1]+1,pos-1))f[i]=max(f[i],pos+x);//第i个人向右走
    		if(ok(f[i-1]+1,pos-x-1))f[i]=max(f[i],pos);//第i个人向左走
    		if(i>1)
    			if(ok(f[i-2]+1,pos-x-1))f[i]=max(f[i],max(p[i-2]+x,pos));//第i个人向左走,第i-1个人向右走
    	}
    	return ok(f[p.size()]+1,n);
    }
    int main()
    {
    	scanf("%d",&n);
    	scanf("%s",ch+1);
    	for(int i=1;i<=n;++i)
    	{
    		s[i]=s[i-1];
    		if(ch[i]=='P')p.pb(i);
    		else if(ch[i]=='*')++s[i];
    	}
    	if(p.size()==1)
    	{
    		int pos=p[p.size()-1];
    		int suml=sum(1,pos-1),sumr=sum(pos+1,n);
    		if(!suml&&!sumr)return puts("0 0"),0;
    		int l=1;while(ok(1,l))++l;
    		int r=n;while(ok(r,n))--r;
    		if(l>pos)return printf("%d %d",sumr,r-pos),0;
    		if(r<pos)return printf("%d %d",suml,pos-l),0;
    		if(suml==sumr)printf("%d %d",suml,min(pos-l,r-pos));
    		else printf("%d %d",max(suml,sumr),suml>sumr?pos-l:r-pos);
    	}
    	else
    	{
    		int l=0,r=n;
    		while(l+1<r)
    		{
    			int mid=l+r>>1;
    			ck(mid)?r=mid:l=mid;
    		}
    		printf("%d %d
    ",sum(1,n),r);
    	}
    	return 0;
    }
    
  • 相关阅读:
    nginx启动时指定配置文件
    idea修改忽视文件产生得bug
    SpringBoot整合RabbitMQ出现org.springframework.amqp.AmqpException: No method found for class
    解决git速度太慢的问题,亲测有效
    HttpRequestException encountered解决方法
    mybatis大于等于小于等于的写法
    Could not initialize class sun.awt.X11GraphicsEnvironment异常处理
    CF377C Captains Mode
    AT1251 たのしいたのしい家庭菜園
    CF1057C Tanya and Colored Candies
  • 原文地址:https://www.cnblogs.com/zmyzmy/p/13741971.html
Copyright © 2020-2023  润新知