我是靠谱客的博主 怡然老虎,最近开发中收集的这篇文章主要介绍比赛经验总结--187,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

cqround1

1.这次比赛160分

(1)反质数:60

(2)二分答案+2sat:验证:  0分

(3)树上LCA+推公式: 100分

2.总结:这次比赛第三题做起来非常顺,做过类似的题:奶牛大集会nkoj3689,树上的lca加乱搞基本上就是这样,注意画一些复杂的图(儿子祖先画全)不要凭空想,因为这种式子很容易推错,这里差一点那里差一点就爆0了。第一题,虽然反质数并没有学过,但是其实仔细想一想是推得出来的,关于反质数,可以看这篇解题报告点击打开链接。第二题超纲,但是看懂了还是感觉很厉害,那么通常什么情况可以使用2sat?对于每一个东西,有两种情况并且必须二选一!


cqround2

1.这次比赛300分

(1)乱搞模拟:100

(2)打铁:100

(3)倒序+并查集:100

2.总结:这次虽说ak了,可以说是运气好吧。当然也是一中的题确实水分比较重,感觉到处找了几道题,有先天优势,第二题做过两次的原题,当年也是自己推出来的。第一题难点在于读题难!这个题也可以提示关于输入:example:255.255.255.247   。怎么读这四个数呢?(1).输入优化直接无视'.'(2)scanf("%d.%d.%d.%d",...)。第三题有人剧透了是并查集,那就是并查集撒。这个题,注意到并查集仅支持合并操作,但此题题意的意思是要断开,正起断开,那么就倒起来合并!这种思想的题是做过的:假期关楼。先把他不断的边连接的节点用并查集合并,与1联通的节点就是掉不下去的。倒序讨论断开的边,合并,在什么时候与1联通,这一块所含节点的ans就是段边的时间。加油!!!


cqround3

1.这次比赛145分!亏的一匹

(1)找规律+组合数取模:25

(2)trie+dp:100

(3)构造序列:20

2.总结:惨!第一题死因:1e9+7打成了1000000009!!!第二题比较好想的dp,对于每一个位置,很显然要找出为当前1--i这个字符串后缀的单词,字典树!第三题确实厉害,难想,看懂了觉得神题一道。


cqround4

1.这次比赛200分

(1)暴力打出来找规律!

(2)观察代码,很简单的gcd

(3)堆+贪心

2.总结:仔细审题!!!第一题最开始没看到(n-1)是(m-1)的倍数,打表找不出规律。第三题确实比较厉害,但是有一个经典的贪心原则,详情见nkoj3827


西南联训6

1.这次比赛200分

(1)dfs,类似重庆排位赛1反质数!

(2)区间dp

(3)图论

2.总结:仔细审题!!!第一题最开始没看到(n-1)是(m-1)的倍数,打表找不出规律。第三题确实比较厉害,但是有一个经典的贪心原则,详情见nkoj3827




cqround5

1.这次比赛190分

(1)分析找通式

(2)树形dp(打铁)

(3)国家队训练题,90分算法(暴力spfa10分+树上lca30分+mst树上lca多一条边单独算50分)

2.总结:第一题不说了,仔细分析还是比较容易,但是尽量少用点时间,这几场第一题都用了一个小时多一点。第二题一道树形dp(打铁),当时确实没做出来,状态定的不对,树形dp要复习一下!第三题能拿到得分都拿到了,拿到题先看看数据范围,10分暴力送分,30分lca(m==n-1),50分mst+lca+单独一条边单独算。正解思路大概懂了,但是目前还是写不出代码。。。


cqround6

1.这次比赛190(200)分(一中第二题数据有一组不合法)

(1)分析找规律

(2)图论dijkstra+top打铁

(3)dfs

2.总结:第一题还是比较容易,对于当前选了一些硬币的和为sum,那么下一枚硬币的面值p必须在1---sum+1之间,这样才能满足选了这枚硬币后,1----sum+p之间的值全部能凑出来,这个是在草稿本上用了10分钟推出来的。那么怎么保证所选硬币个数最少呢?因为p必须在1---sum+1之间,当然取区间中面值最大的,一定是最优的。其实仅仅就是这样很容易卡,比如1e9 2 1 2这样的数据不管是循环还是递归都会死掉,后面又想出来了这个东西。当sum>=p[n]即和不小于最大面值的硬币的时候,根据前面提到的原则肯定就选p[n]!这个时候就不需要再去模拟了,直接除就行了,这个是肯定卡不掉的。一中数据太辣鸡,导致写暴力的人都a了。第二题大水题,反向最短路+top打铁。第三题dfs,dfs再一次的死了,搜索能力还需加强!关于这个题,最开始是写的搜完了再check,但是发现边搜边check效率高到爆炸,详情参见nkoj3849游戏!


10.31的一个智障错!

新oj真的良心,爆0的代码拿了95分。三分法的下界没赋初值!能拿多少分全凭运气!记住非全局变量记得赋初值




11.3模拟赛

1.这次比赛170分

(1)暴力送分题100

(2)正解:双hash,送的50分拿好。

(3)正解dp,dfs30分剪枝剪成了20分

2.总结:先说第二题,本来考试的时候想到了hash,并且在考虑一个子串---->下一个子串时,如何在O(1)的复杂度内处理出下一个子串的hash。但是,hash学的撇!不知道hash可以直接这么搞!

以今天第二题为例:好文章

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
#define ull unsigned long long
#define puu pair<ull,ull>
#define mp make_pair
using namespace std;
const ull seed1=31;
const ull seed2=131;
const ull mod1=1875647;
const ull mod2=3838437;
inline void _read(int &x){
    char t=getchar();bool sign=true;
    while(t<'0'||t>'9')
    {if(t=='-')sign=false;t=getchar();}
    for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0';
    if(!sign)x=-x;
}
ull temp1=1,temp2=1;
ull hash1,hash2;
int n,m;
char s[200005];
puu ans[200005];
ull tot=0;
int main(){
	int i,j,k;
	cin>>n>>m;
	scanf("%s",s+1);
	for(i=1;i<=m;i++){
		hash1=(hash1*seed1+s[i])%mod1;
		hash2=(hash2*seed2+s[i])%mod2;
		temp1=temp1*seed1%mod1;
		temp2=temp2*seed2%mod2;
	}
	ans[++tot]=mp(hash1,hash2);
	for(i=m+1;i<=n;i++){
		hash1=(hash1*seed1%mod1+s[i]+mod1-temp1*s[i-m]%mod1)%mod1;
		hash2=(hash2*seed2%mod2+s[i]+mod2-temp2*s[i-m]%mod2)%mod2;
		ans[++tot]=mp(hash1,hash2);
	}
	sort(ans+1,ans+1+tot);
	tot=unique(ans+1,ans+1+tot)-ans-1;
	cout<<tot;
}



原型BKDRhash。O(1)转移出下一个长度为m的子串的hash,hash每处理一个新的元素乘一次seed,因为子串长度为m,一个元素从进入这个hash到离开,乘了m次seed,减去即可!注意不要乱取模,hash是一门玄学,可以记住这个写法!

下面说说第三题:好线路

考试的时候推出了这一个很关键的式子:要求的:方差*(n+m-1)^2,令n-m+1=k,可化简为:k*(x1^2+x2^2+..+xk^2)-(x1+x2+..xk)^2。然而想出了这个式子却还是想着dfs!!!想dp的时候却想的是方差的定义式,有后效性。dp该从我推出的这个式子入手!想一想把xk这个项分离出来跟前面的x1....xk-1产生关系。于是得到:k*(x1^2+x2^2+...xt^2)-(x1+x2+...xt)^2 = k*(x1^2+x2^2+...+xt-1^2)-(x1+x2+...+xt-1)^2+k*xt^2  -xt^2 - 2*(x1+x2+...+xt-1)*xt =  k*(x1^2+x2^2+...+xt-1^2)-(x1+x2+...+xt-1)^2 +(k-1)*xt^2 -2*(x1+x2+...+xt-1)*xt

递推关系出来了,dp!

f[i][j][s]:当前的到第i行第j列,并且当前路径上的权值和为s,这个式子k*(x1^2+x2^2+...xt^2)-(x1+x2+...xt)^2的最小值。

由之前推出的式子:

f[i][j][s]=min ( f[i][j-1][s-map[i][j]] , f[i-1][j][s-map[i][j]] ) + (k-1) * ( map[i][j] ) ^ 2  -  2 * ( s - map[i][j] ) * map[i][j]

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
const int inf=0x3f3f3f3f;
inline void _read(int &x){
    char t=getchar();bool sign=true;
    while(t<'0'||t>'9')
    {if(t=='-')sign=false;t=getchar();}
    for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0';
    if(!sign)x=-x;
}
int n,m,k;
int ans=inf;
int map[55][55];
int f[55][55][5000];
int minn[55][55];
int maxn[55][55];
int lim;
int main(){
	int i,j,h,s;
	cin>>n>>m;
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			cin>>map[i][j];
		}
	}
	k=n+m-1;
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			minn[i][j]=min(minn[i-1][j],minn[i][j-1])+map[i][j];
			maxn[i][j]=max(maxn[i-1][j],maxn[i][j-1])+map[i][j];
		}
	}
	lim=maxn[n][m];
	//f[1][1][map[1][1]]=(k-1)*map[1][1]*map[1][1];
	for(i=0;i<=n;i++){
		for(j=0;j<=m;j++){
        	for(s=0;s<=lim;s++){
            	f[i][j][s]=inf;
        	}
    	}
    }
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			if(i==1&&j==1){
				f[i][j][map[1][1]]=(k-1)*map[1][1]*map[1][1];
				continue;
			}
			for(s=minn[i][j];s<=maxn[i][j];s++){
				f[i][j][s]=min(f[i-1][j][s-map[i][j]],f[i][j-1][s-map[i][j]])+(k-1)*map[i][j]*map[i][j]-2*(s-map[i][j])*map[i][j];
			}
		}
	}
	for(i=minn[n][m];i<=maxn[n][m];i++){
		ans=min(ans,f[n][m][i]);
	}
	cout<<ans;
}


cqround8

1.这次比赛170,最垃圾的一次

(1)dp100分

(2)单调队列(栈),类似于广告牌模型

(3)类似gcd递归解决

2.总结:这次比赛值得好还反省!有史以来最丑的一次!第一题稍微提一下,注意到贪心是有问题的!第二题,思维方向有问题,我想的是先枚举点,再看包含这个点的子矩阵。而实际上对于这种题,应该先枚举矩阵,再来看其中的最小值是什么!比如今天这个题,应该枚举第i排到第j排再看区间中的最小值,min[k]表示第k列中,第i排到第j排的最小值,对于第i排到第j排之间,要让min[k]是子矩阵中的最小值,考虑k往两边延展,例如往左找到第一个小于min[k]的min[h],那么记left[k]=h+1,即k往左最多可以延展到h,往右同理,记right[k],那么right,left怎么处理,往左第一个比自己小的:单调队列!那么对于第i排到第j排中,以min[k]为最小值的子矩阵个数很显然就是(right[k]-k+1)*(k-left[k]+1)说说第三题,正难则反!倒过来思考,状态(a,b)令(a>=b)可以转移至(a+k*b,b),那么倒过来也就很简单了,用类似于gcd的方式倒过来计算,work(x,y)表示到状态(x,y)所需的步数(令x>=y)。而题目要求至少一个为n,那么就取work(n,i)的最小值即可。


对拍模板

@echo off
:loop
makedata.exe
baoli.exe
zhengjie.exe
fc baoli.out ans.out
if not errorlevel 1 goto loop
pause
:end


最后

以上就是怡然老虎为你收集整理的比赛经验总结--187的全部内容,希望文章能够帮你解决比赛经验总结--187所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部