zoukankan      html  css  js  c++  java
  • CF1236E Solution

    题目链接

    题解

    ⭐:为保证无后效性可以尝试倒序

    如果下一个盒子会猜中,便在当前盒子中停留,如此可见对于每一个起始位置,可以到达的最终位置是连续的,因此可以求出其左右端点。设娃娃要由(i)号盒子转移至(j)号盒子中((i<j)),可以发现在某处停留一次与由(i-1)号盒子出发产生的后果相同,因此最右终点位置即为(i+m-)停留次数。但是若枚举全部起点时间复杂度为(O(n^2)),无法通过。又因为每个猜测(a_i)只可影响到(a_i+i)(a_i-i)两个起点,所以只需将起点(a_i-i)的停留次数由(a_i-i-1)转移来并(+1)。但是同一个起点也许可以受到多次猜测的影响,这时真正影响其的为(i)最小的猜测,因此须倒序枚举(a)。倒序枚举同时解决了当前停留对之后是否停留的影响,因为其后已处理过了。上述为(i<j)(向右移)的情况,(i>j)(向左移)同理。

    AC代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=3e5+10,qwq=1e5+10;
    int a[N],l[N],r[N];//l/r[i]:以a[i]为起点向左/右移动的停留次数
    signed main()
    {
    	int n,m,ans=0;
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=m;i++) scanf("%lld",&a[i]);
    	if(n==1) {printf("0"); return 0;}
    	for(int i=m;i>=1;i--) 
    		l[a[i]+i+qwq]=l[a[i]+i+1+qwq]+1,r[a[i]-i+qwq]=r[a[i]-i-1+qwq]+1;
    	for(int i=1;i<=n;i++)
    	{
    		int x=max(1ll,i-(m+1)+l[i+qwq]),y=min(n,i+(m+1)-r[i+qwq]);
    		ans+=y-x+1;
    	}
    	printf("%lld",ans);
    	return 0;
    }	
    
  • 相关阅读:
    String、StringBuffer与StringBuilder之间区别
    关于 hashCode() 你需要了解的 3 件事
    Java基础之 运算符
    Java基础之基础语法
    Java基础之Java 修饰符
    自动化-python介绍与基础
    vue访问本地后台
    vue请求报错Uncaught (in promise)
    使用vue-resource,get、post、jsonp都报未定义的错误。
    【蓝桥杯】历届试题 打印十字图
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14556203.html
Copyright © 2011-2022 走看看