• 吉大第二届青云杯复赛第6题


    题目链接

    题意分析

    我就是死在了这道题上

    首先我们可以明白的是 所有(a_i)增加的上限就是(lim=Min_{1≤i≤n}b_i)

    然后我们令(c_i=lim-b_i)

    如果存在(c_i<0)的话 那是绝对不符合要求的

    这样的话我们的操作就变成了

    1.选择一个(k(1≤k≤n))使得所有(c_1,c_2,...,c_k)全部(-1)

    2.选择一个(k(1≤k≤n))使得所有(c_k,c_{k+1},...,c_n)全部(-1)

    然后的话 我们就是躲过这两种操作使得所有(c_i)相等并且都是(≥0)

    当时想到了这里 然后就走歪了 但是当时也明白 这道题的正解应该是比较简单的

    但是真正看到正解的那一刻 我还是震惊到了

    整体加减 我们想到了什么 差分!!!

    我们让(c_0=0) 然后的话(d_i=c_i-c_{i-1}(1≤i≤n))

    然后我们再回头看这两种操作

    1.选择一个(k(1≤k≤n))使得(d_1-1,d_{k+1}+1)

    2.选择一个(k(1≤k≤n))使得(d_k-1)

    然后的话 我们就是看看

    [d_1 + sum_{i=2}^n{[d_i<0]d_i}≥0 ]

    这样的话就可以了

    CODE:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #define N 1000080
    using namespace std;
    int T,n,lim,tot;
    bool flag;
    int cdy[N],wzy[N],num[N],d[N];
    int main()
    {
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d",&n);lim=2100000000;flag=0;tot=0;
    		for(int i=1;i<=n;++i) scanf("%d",&cdy[i]);
    		for(int i=1;i<=n;++i) scanf("%d",&wzy[i]);
    		for(int i=1;i<=n;++i) lim=min(lim,wzy[i]);
    		for(int i=1;i<=n;++i) num[i]=lim-cdy[i];
    		for(int i=1;i<=n;++i) if(num[i]<0) {flag=1;break;}
    		if(flag) {puts("No");continue;}
    		for(int i=1;i<=n;++i) d[i]=num[i]-num[i-1];
    		for(int i=1;i<=n;++i)
    		if(i==1) tot+=d[i];
    		else if(d[i]<0) tot+=d[i];
    		if(tot>=0) puts("Yes");
    		else puts("No"); 
    	}
    	return 0;
    }
    
  • 相关阅读:
    RedGlove 权限管理系统(1)权限概述
    SPQuery查询语法简要说明
    DataGridView使用技巧大全
    实战asp.net MVC+ADO.NET EntityFramework
    RedGlove 权限管理系统(2)功能模块设计
    C# 如果何从线程中操作控件
    PageHelper 类 和 ValidateHelper 类
    字符串帮助类
    XMLHelper 类
    Android中截取当前屏幕的功能
  • 原文地址:https://www.cnblogs.com/LovToLZX/p/14058900.html
Copyright © 2020-2023  润新知