Educational Codeforces Round 73 (Rated for Div. 2)

A - 2048 Game

题意:问数组中数的组成是否能组成2048,其中的数都是2的幂。
题解:都是2的幂所以将小于2048的数加起来最后能大于等于2048即可。

#include <cstdio>
#include <algorithm>
using namespace std ; 
int main(){
	int t ; 
	scanf ("%d",&t) ; 
	while(t --){
		int n , x , sum = 0 ; 
		scanf ("%d",&n) ;
		for (int i = 0 ; i < n ; ++ i){
			scanf ("%d",&x) ; 
			if (x <= 2048)	sum += x ; 
		}
		if (sum >= 2048)	printf ("YES\n") ; 
		else	printf ("NO\n") ; 
	}
	return 0 ; 
}
B - Knights

题意:蓝色格子可以吃到红色格子的,现有黑白两种棋,问怎么摆放使得白棋可以吃更多黑棋(可重复吃)
在这里插入图片描述
题解:同奇偶行的摆放白棋,其他都是黑棋即可。

#include <cstdio>
int main(){
	int n ; 
	scanf ("%d",&n) ; 
	for (int i = 1 ; i <= n ; ++ i){
		for (int j = 1 ; j <= n ; ++ j){
			if (i%2==1 && j%2==1)	printf ("W") ; 
			else if (i%2==0 && j%2==0)	printf ("W") ;
			else	printf ("B") ; 
		}
		printf ("\n") ;
	}
	return 0 ; 
}
C - Perfect Team

题意:一个三人的队伍里必须要有一个coder 和一个math,剩下一个随意,先给出c m x表示三种人的个数,问最多能组成多少队。
题解:最多的情况是三者相加除于3,但是必须有一个c 和一个m那么就受到这两个数目的限制,两者最少的即为组成最多的队伍,所以两者取最小值即可。

#include <cstdio>
#include <algorithm>
using namespace std ; 
int main(){
	int t ; 
	scanf ("%d",&t) ; 
	while(t --){
		int c , m , x ; 
		scanf ("%d%d%d",&c,&m,&x);
		printf ("%d\n",min((c+m+x)/3,min(c,m))) ;
	}
	return 0 ; 
}
D - Make The Fence Great Again

题意:给出栅栏的每一个高度和增加一米的耗费,要求相邻栅栏的高度不能相同,问耗费最少是多少。
题解:dp[i][0/1/2] 表示该栅栏不增 / 增一米 / 增两米的耗费,因为只是要求相邻不一样高度所以最多也就增两米,
状态转移方程:

for (ll j = 0 ; j < 3 ; ++ j){	//枚举i-1的增长量 
	for (ll k = 0 ; k < 3 ; ++ k){	//枚举i的增长量 
		if (a[i-1]+j != a[i]+k){
			dp[i][k] = min(dp[i][k],dp[i-1][j]+b[i]*k) ;
		}
	}	
}
#include <cstdio>
#include <algorithm>
using namespace std ;
typedef long long ll ;
const int N= 3e5 + 10 ;
const ll INF = 1e18 ; 
ll a[N] , b[N] ;
ll dp[N][3] ; 
int main(){
	int t ; 
	scanf ("%d",&t) ; 
	while(t --){
		ll n ; 
		scanf ("%lld",&n) ;
		for (int i = 1 ; i <= n ; ++ i){
			scanf ("%lld%lld",&a[i],&b[i]) ;
			dp[i][0] = dp[i][1] = dp[i][2] = INF ; 
		}
		dp[1][0] = 0 , dp[1][1] = b[1] , dp[1][2] = 2*b[1] ; 
		for (ll i = 2 ; i <= n ; ++ i){
			for (ll j = 0 ; j < 3 ; ++ j){	//枚举i-1的增长量 
				for (ll k = 0 ; k < 3 ; ++ k){	//枚举i的增长量 
					if (a[i-1]+j != a[i]+k){
						dp[i][k] = min(dp[i][k],dp[i-1][j]+b[i]*k) ;
					}
				}	
			}
		}
		printf ("%lld\n",min(dp[n][0],min(dp[n][1],dp[n][2]))) ;
	}
	return 0 ; 
}


刚看到这道题就觉得是dp但是我只用了dp[i][0/1]来表示状态然后也一直在想如果是a[i-1] == a[i] , a[i]+1==a[i+1] 的情况怎么办 用不用改变a数组什么的。唉,做了这么久的dp还是没做出来还是有些失望的,可能还是题刷的太少了。┭┮﹏┭┮

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值