zoukankan      html  css  js  c++  java
  • [NOIP模拟赛] 2021.11.16

    T1

    对所有长度大于等于3的子区间计算长高成山峰的花费和,一个区间长高成山峰的花费等于每个数字增大的花费和。

    DDG的牛逼单调栈,危黑灵永远游荡在我们周围!

    枚举的是山峰,算贡献只算到这个山峰的。

    极短代码
    //12252024832524
    #include <bits/stdc++.h>
    #define TT template<typename T>
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 1000005;
    const int MOD = 1e9+7;
    int n,ans;
    int a[MAXN];
    
    LL Read()
    {
    	LL x = 0,f = 1; char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    int s[MAXN],tl;
    
    int main()
    {
    //	freopen("mountain.in","r",stdin);
    //	freopen("mountain.out","w",stdout);
    	n = Read();
    	for(int i = 1;i <= n;++ i) a[i] = Read();
    	for(int i = 1;i <= n;++ i)
    	{
    		while(tl && a[i] >= a[s[tl]])
    		{
    			if(tl > 1) ans = (ans + (n-i+1ll) * (Min(a[i],a[s[tl-1]])-a[s[tl]]) % MOD * (i-s[tl-1]-1) % MOD * s[tl-1] % MOD) % MOD;
    			--tl; 
    		}
    		s[++tl] = i;
    	}
    	Put(ans,'\n');
    	return 0;
    }
    //426406027
    
    

    T2

    赛时切了,是个比较简单的背包。

    赛时代码
    //12252024832524
    #include <bits/stdc++.h>
    #define TT template<typename T>
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 55;
    const int MAXA = 505;
    const int B = 51*500;
    const int C = 500;
    int n,m,ans;
    int a[MAXN][MAXN];
    int dp[2][B<<1|5],r[MAXN][MAXA<<1],c[MAXN][MAXA<<1];
    
    LL Read()
    {
    	LL x = 0,f = 1; char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    int main()
    {
    	freopen("matrix.in","r",stdin);
    	freopen("matrix.out","w",stdout);
    	n = Read(); m = Read();
    	for(int i = 0;i < n;++ i)
    		for(int j = 0;j < m;++ j) 
    			a[i][j] = Read();
    	for(int i = 0;i < n;++ i)
    		for(int j = 0;j < m;++ j)
    		{
    			int to = (i-1+n)%n;
    			++r[i][a[i][j]-a[to][j]+C];
    		}
    	for(int i = 0;i < n;++ i)
    		for(int j = 0;j < m;++ j)
    		{
    			int to = (j-1+m)%m;
    			++c[j][a[i][j]-a[i][to]+C];
    		}
    	int L = B,R = B;
    	for(int i = 1;i < n;++ i)
    	{
    		bool now = i&1,to=now^1;
    		memset(dp[now],0,sizeof(dp[now]));
    		int M = 0;
    		for(int j = L;j <= R;++ j) M = Max(M,dp[to][j]);
    		for(int j = L;j <= R;++ j)
    		{
    			for(int kk = 0,k;kk < m;++ kk)
    			{
    				k = a[i][kk] - a[i-1][kk];
    				dp[now][j+k] = Max(dp[now][j+k],dp[to][j]+r[i][k+C]);
    			}
    		}
    		L -= 500; R += 500;
    		for(int j = L;j <= R;++ j) dp[now][j] = Max(dp[now][j],M);
    	}
    	int val = 0;
    	for(int i = L;i <= R;++ i) val = Max(val,dp[(n-1)&1][i]+((C-(i-B) >= 0 && C-(i-B) <= 1000) ? r[0][C-(i-B)] : 0));
    	ans += val;
    	//---
    	L = B,R = B;
    	memset(dp[0],0,sizeof(dp[0]));
    	for(int i = 1;i < m;++ i)
    	{
    		bool now = i&1,to=now^1;
    		memset(dp[now],0,sizeof(dp[now]));
    		int M = 0;
    		for(int j = L;j <= R;++ j) M = Max(M,dp[to][j]);
    		for(int j = L;j <= R;++ j)
    		{
    			for(int kk = 0,k;kk < n;++ kk)
    			{
    				k = a[kk][i] - a[kk][i-1];
    				dp[now][j+k] = Max(dp[now][j+k],dp[to][j]+c[i][k+C]);
    			}
    		}
    		L -= 500; R += 500;
    		for(int j = L;j <= R;++ j) dp[now][j] = Max(dp[now][j],M);
    	}
    	val = 0;
    	for(int i = L;i <= R;++ i) val = Max(val,dp[(m-1)&1][i]+((C-(i-B) >= 0 && C-(i-B) <= 1000) ? c[0][C-(i-B)] : 0));
    	ans += val;
    	Put(ans,'\n');
    	return 0;
    }
    /*
    可以考虑 ri-1 和 ri 满足什么关系可以获得贡献
    地球是个环,所以还是有关的,但是可以dp
    这负数真的恶心至极 
    */
    

    T3

    \/ 不要正方形构造题。

    考虑翻转调整字典序必定变小,所以直接费用流。

    只需从左上到右下定义费用逐渐增大即可,因为费用流优先增广费用小的。

    还可以暴力调整,但是复杂度劣一些。

    T4

    给定一些字符必须转换,可以多次进行,求最大保留字符种类。

    差两点。

    一点是没相当转化成匹配问题,一点是题面出锅打一半就觉得完全不可做。

    其实就是字符去填空,缩点之后变成很多强连通分量。

    一些是需要转化的,一些是可以内部消耗边的(有空的)。

    需要转化的连向可以转到的点(可以也是需要转化的点),最大匹配就是可以保留的最多的字符种类。

    注意一些本来就没有的字符不要算到贡献里面。

  • 相关阅读:
    Python+selenium常见报错
    jmeter压力测试指标解释
    jemte自动生成测试报告方法
    iview清空Date-picker组件后请求报错解决方法
    【求助】Django+vue项目时候遇到一个问题,table的data数据怎么更新
    django_数据库操作—增、删、改、查
    django-关于manage.py migrate无效的问题
    python家里的环境和公司环境怎么同步
    python class类的属性应用及init初始化实践 ---勇者斗恶龙
    IDLE与pycharm执行相同代码结果却不同,原因分析
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/15561989.html
Copyright © 2011-2022 走看看