格子

【苏州国庆营模拟】Day2 A.divide

ε祈祈猫儿з 提交于 2019-12-01 01:28:01
题目链接 题意:   对一个$n$行$m$列的网格黑白染色,满足:   1.黑色的格子两两四联通,白色格子两两四联通,且黑色的格子经过旋转和平移可以和白色的格子重合   2.$w(wx,wy)$这个格子是白色的,$b(bx,by)$这个格子是黑色的。   要求找到任意一个解,或者判断无解。多组数据。   $1\le T\le 10^3, \;1\le n,m\le 50, \;1\le wx,bx\le n, \; 1\le wy,by\le m ,\; (wx,wy)\neq(bx,by)$ 分析:   首先考虑什么时候无解。   ①网格数为奇数,无法均分   ②仅有单行/单列且指定黑白格在同侧,也无法均分   接下来分类讨论:   ①若$2|m$(可通过整张图旋转$90^{\circ}$得到,下同),且两个指定点分居中线两侧,则直接对切。   ②若指定点居于中线同侧,且在不同行,可如上图染色。   ③若指定点居于中线异侧,且在相同行,离中线近的指定点不在最后一行,可如上图染色。 实现: #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<queue> #define IL inline #define

acWing 275. 传纸条

人盡茶涼 提交于 2019-11-30 19:30:51
题意: 给定一个 N*M 的矩阵A,每个格子中有一个整数。 现在需要找到两条从左上角 (1,1) 到右下角 (N,M) 的路径,路径上的每一步只能向右或向下走。 路径经过的格子中的数会被取走,两条路径可以经过同一个格子,但格子中的数 只能被取一次。 求取得的数之和最大是多少。 输入格式 第一行有2个用空格隔开的整数n和m,表示矩阵有n行m列。 接下来的n行是一个n*m的矩阵,每行的m个整数之间用空格隔开。 输出格式 输出一个整数,表示答案。 数据范围 1 ≤ n , m ≤ 50 1≤n,m≤50 输入样例: 3 3 0 3 9 2 8 5 5 7 0 输出样例: 34题解: 首先考虑路径有交集该如何处理。 可以发现交集中的格子一定在每条路径的相同步数处。因此可以让两个人同时从起点出发,每次同时走一步,这样路径中相交的格子一定在同一步内。 状态表示:f[k, i, j] 表示两个人同时走了k步,第一个人在 (i, k - i) 处,第二个人在 (j, k - j)处的所有走法的最大分值。 状态计算:按照最后一步两个人的走法分成四种情况: 两个人同时向右走,最大分值是 f[k - 1, i, j] + score(k, i, j); 第一个人向右走,第二个人向下走,最大分值是 f[k - 1, i, j - 1] + score(k, i, j); 第一个人向下走,第二个人向右走

【国庆集训】 10.1

拈花ヽ惹草 提交于 2019-11-30 18:59:22
说实话,这次考试只有第三题恶心一点,太菜的我只有100,第二题写了正解没过 T1 1.爬山(mountain.cpp) 题目描述 FGD 小朋友特别喜欢爬山,在爬山的时候他就在研究山峰和山谷。为了能够让 他对他的旅程有一个安排,他想知道山峰和山谷的数量。给定一个地图,为 FGD 想要旅行的区域,地图被分为 n*n 的网格,每个格子(i,j) 的高度 w(i,j)是给定的。 若两个格子有公共顶点(八连通),那么他们就是相邻的格子。我们定义一个格子 的集合 S 为山峰(山谷)当且仅当: 1. S 的所有格子都有相同的高度。 2. S 的所有格子都联通 3. 对亍 s 属亍 S,不 s 相邻的 s’丌属亍 S。都有 ws > ws’(山峰),戒者 ws < ws’(山谷)。 你的任务是,对亍给定的地图,求出山峰和山谷的数量,如果所有格子都有相同 的高度,那么整个地图即是山峰,又是山谷。 输入格式 第一行包含一个正整数 n,表示地图的大小(1<=n<=1000)。接下来一个 n*n 的矩阵,表示地图上每个格子的高度。 (0<=w<=1000000000) 输出格式 应包含两个数,分别表示山峰和山谷的数量。 输入输出样例 in: 5 8 8 8 7 7 7 7 8 8 7 7 7 7 7 7 7 8 8 7 8 7 8 8 8 8 out: 2 1 好吧,一道小水题(捂脸),也就想了半个小时

Codeforces 1196E. Connected Component on a Chessboard

落爺英雄遲暮 提交于 2019-11-30 16:05:20
传送门 注意到棋盘可以看成无限大的,那么只要考虑如何构造一个尽可能合法的情况 不妨假设需要的白色格子比黑色格子少 那么容易发现最好的情况之一就是白色排一排然后中间黑的先连起来,剩下黑色的再全部填白色周围 可以证明如果需要 $w$ 个白色格子,那么黑色格子的数量不能超过 $3w+1$ 证明:首先 $w=1$ 时显然 然后考虑下一个白色格子扩展,显然从一边延伸出去,然后又多了 $3$ 个可以放黑色的位置,这样一路扩展显然可以放 $3w+1$ 个黑色的位置 然后考虑证明没有更好的方案,显然除了第一次白色可以提供四个黑色位置以外,之后放扩展白色时,至少要有其中一边和原本的黑色相邻,那么每次扩展多就只能多 $3$ 个合法位置 证明完毕 然后直接按构造的搞就行了,注意一下细节就行 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<

AcWing 車的放置

我的未来我决定 提交于 2019-11-29 17:44:50
AcWing 車的放置 Description 给定一个N行M列的棋盘,已知某些格子禁止放置。 问棋盘上最多能放多少个不能互相攻击的車。 車放在格子里,攻击范围与中国象棋的“車”一致。 Input 第一行包含三个整数N,M,T,其中T表示禁止放置的格子的数量。 接下来T行每行包含两个整数x和y,表示位于第x行第y列的格子禁止放置,行列数从1开始。 Output 输出一个整数,表示结果。 Data Size 1≤ N , M ≤200 题解: 二分图匹配。 比较简单。如果在一个格子放置了棋子,那么棋子所在那一列,那一行,都不能放了。抽象一下,把每行抽象成左边的一组点,每列抽象成右边的一组点。放置一个棋子就等于把其所在行的点向其所在列的点连一条边。显然,要放尽可能多的棋子就要凑成尽可能多对连线。那么就是二分图匹配了。 #include <iostream> #include <cstdio> #include <cstring> #define N 205 using namespace std; struct E {int next, to;} e[N * N]; int n, m, t, num, ans; int h[N], mat[N]; bool vis[N]; bool tag[N][N]; void add(int u, int v) { e[++num].next =

专题——四维DP

送分小仙女□ 提交于 2019-11-28 00:50:36
因为在做题的时候常常做不出来,一看题解大呼“竟然有四维”,所以我决定整理一下四维DP的问题。 T1 P1004 方格取数 题目描述 设有N×N的方格图(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0。如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 B 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。 此人从A点到B点共走两次,试找出2条这样的路径,使得取得的数之和为最大。 输入格式 输入的第一行为一个整数NN(表示N \times NN×N的方格图),接下来的每行有三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的00表示输入结束。 输出格式 只需输出一个整数,表示22条路径上取得的最大的和。 解法 其实如果只走一条路径完全可以直接二维dp出来。但是这题有一个特殊的地方, 那就是取走的地方会变为0.这就不允许我们分别DP。在这种情况下,我们要参考数据范围,然后发现,可以设f[i][j][p][q

[Jzoj] 1035.【SCOI2009】粉刷匠

送分小仙女□ 提交于 2019-11-26 19:12:07
题目大意 w i n d y windy w i n d y 有 N N N 条木板需要被粉刷。 每条木板被分为 M M M 个格子。 每个格子要被刷成红色或蓝色。 w i n d y windy w i n d y 每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被粉刷一次。 如果 w i n d y windy w i n d y 只能粉刷 T T T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。 题目解析 D P DP D P 设 f [ i , j , k , 0 / 1 ] f[i,j,k,0/1] f [ i , j , k , 0 / 1 ] 表示前 i i i 个木板,涂色到第 i i i 个木板的第 j j j 个,粉刷了 k k k 次,且第 i , j i,j i , j 个的格子涂成 0 / 1 0/1 0 / 1 的最大值。 当 j = 1 j=1 j = 1 时, f [ i , j , k , 0 ] = m a x ( f [ i − 1 , m , k − 1 , 0 ] , f [ i − 1 , m , k − 1 , 1 ] ) f[i,j,k,0]=max(f[i-1,m,k-1,0],f[i-1,m,k-1,1]) f [ i , j , k , 0 ] = m a

JZOJ 1035. 【SCOI2009】粉刷匠

ぃ、小莉子 提交于 2019-11-26 19:02:34
题目 Description windy有 N 条木板需要被粉刷。 每条木板被分为 M 个格子。 每个格子要被刷成红色或蓝色。 windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被粉刷一次。 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。 Input 第一行包含三个整数,N M T。 接下来有N行,每行一个长度为M的字符串,'0'表示红色,'1'表示蓝色。 Output 输出一个整数,表示最多能正确粉刷的格子数。 Sample Input 3 6 3 111111 000000 001100 Sample Output 16 Data Constraint Hint 100%的数据,满足 1 <= N,M <= 50 ; 0 <= T <= 2500 。 分析 设f[i][j][0/1]为前i个格子刷了j次,当前第i格的颜色为0/1 显然 r=((i-1)*m)+j; if (j!=1) f[r][k][0]=max(f[r-1][k][0],f[r-1][k-1][1]), f[r][k][1]=max(f[r-1][k][1],f[r-1][k-1][0]); else f[r][k][0]=max(f[r-1][k-1][0],f[r-1][k-1][1]), f[r]

D9题解

别说谁变了你拦得住时间么 提交于 2019-11-26 17:56:19
1035. 粉刷匠 (Standard IO) Time Limits: 5000 ms Memory Limits: 65536 KB Goto ProblemSet Description windy有 N 条木板需要被粉刷。 每条木板被分为 M 个格子。 每个格子要被刷成红色或蓝色。 windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被粉刷一次。 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。 Input 第一行包含三个整数,N M T。 接下来有N行,每行一个长度为M的字符串,'0'表示红色,'1'表示蓝色。 Output 输出一个整数,表示最多能正确粉刷的格子数。 Sample Input 3 6 3 111111 000000 001100 Sample Output 16 Data Constraint Hint 100%的数据,满足 1 <= N,M <= 50 ; 0 <= T <= 2500 。 代码 /*区间dp,再背包dp f[i][j]=前i个格子刷j次的最多正确格子数 每次枚举一个中间点l 使得f[i][j]=max{f[l][j-1]+v[l,i]} v[l,i]=[l,i]一次涂满相同颜色后获得的正确格子数(0或1) */ #include