To_Heart—总结——CSP-J2020

一、游记

Day 0

在家里复习,毫无规划意识,一会复习下贪心,一会复习下二分,后来发现其他人在复习LCA,于是赶紧放下手中的贪心题,去看一下Tarjan吧。。。

于是瞎搞到十点半,发现自己什么都没有复习到,忧心忡忡地去睡觉了。

Day 1

六点半起床,迷迷糊糊的上了车。

到了场地后,和大家在外面一起拍了照,小黄鸭的邪魅一笑,开了一会玩笑,就进场了。

发现键盘特别不好用,换行贼大,退格贼小,适应了一下,就开始了。

T1,不会,于是手推了一下,发现是签到题。

T2,不会,发现可以用两个优先队列来判断P上和P下,但是写不来小根堆。。。

T3,这不是我最爱的模拟吗???暴力模拟,30分到手。

T4,告诉我们不要乱看题,我把方向看成了4个方向都可以走,于是只会打DFS了。。。

还有一个多小时,发现T3过不了大样例,于是又去改,后来过了大样例,发现时间复杂度不对,于是尝试标记每个点是否会对答案产生影响,于是在输入的时候对ans数组初始化,发现没用,但如果每次操作都改变ans好像有用???

然后神奇的发现,又改成暴力了。。。

二、题解

T1

solution

二进制拆分。

#include<bits/stdc++.h>
using namespace std;

int n;
int sum[100005];

int main(){
    
    
	scanf("%d",&n);
	int tot=0;
	for(int i=2;i<=n;i*=2){
    
    
		sum[++tot]=i;
	}
	if(n%2==0){
    
    
		for(int i=tot;i>=1;i--){
    
    
			if(sum[i]<=n){
    
    
				n-=sum[i];
				printf("%d ",sum[i]);
			}
			if(n==0){
    
    
				return 0;
			}
		}
		return 0;
	}
	printf("-1");
	return 0;
}

T2

solution

因为数据规定,每个数不大于600,所以可以想到用桶来储存,如果i出现,就将tot[i]+1,每次输出时从后往前遍历桶,如果到达了要求的人数,就输出当前的桶。

#include<bits/stdc++.h>
using namespace std;

int a[1000005];
int tot[605]={
    
    }; 
int n,m;

int main(){
    
    
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
    
    
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n;i++){
    
    
		tot[a[i]]++;
		int ans=0;
		int p=max(1,i*m/100);
		for(int j=600;j>=1;j--){
    
    
			ans+=tot[j];
			if(ans>=p){
    
    
				printf("%d ",j);
				break;
			}
		}
	}
	return 0;
}

T3

solution

不会。。。

T4

solution

dp[i][j][0]表示其是由其左侧点或上侧点更新
dp[i][j][1]表示其是由其左侧点或下册点更新
因为点(n,m)只能由其上侧或左侧的点更新,所以答案即为dp[n][m][0]

#include<bits/stdc++.h>
using namespace std;
#define ll long long

ll dp[1005][1005][5];
ll a[1005][1005];
ll n,m;

ll Max(ll a,ll b){
    
    
	return a>b?a:b;
}

int main(){
    
    
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++){
    
    
		for(int j=1;j<=m;j++){
    
    
			scanf("%lld",&a[i][j]);
		}
	}
	memset(dp,-0x3f,sizeof dp);
	dp[1][0][0]=0;
	for(int j=1;j<=m;j++){
    
    
		for(int i=1;i<=n;i++){
    
    
			dp[i][j][0]=Max(dp[i-1][j][0],Max(dp[i][j-1][0],dp[i][j-1][1]))+a[i][j];
		}
		for(int i=n;i>=1;i--){
    
    
			dp[i][j][1]=Max(dp[i+1][j][1],Max(dp[i][j-1][0],dp[i][j-1][1]))+a[i][j];
		}
	}
	printf("%lld",dp[n][m][0]);
	return 0;
	
}

Supongo que te gusta

Origin blog.csdn.net/xf2056188203/article/details/109680315
Recomendado
Clasificación