SRM 514 DIV1 500pt(DP)
给定一个H×W大小的矩阵,每个格子要么是1~9中的一个数,要么是".",要求你把“.”填成具体的数字(1~9),并且符合以下两个要求:
- 对于所有的整数r 和 c( 0 <= r <= H-n,0 <= c < W), 使得 F[r][c] + F[r+1][c] + ... + F[r+n-1][c] 是奇数.
- 对于所有的整数 r 和c(0 <= r < H,0 <= c <= W-m), 使得 F[r][c] + F[r][c+1] + ... + F[r][c+m-1] 是奇数
题解
我们可以发现F[r][c]和 F[r+n][c]的奇偶性是一样的,同样F[r][c]和F[c+m]也是同样的奇偶性,那么我们可以把F[r+p*n][c+q*m]的可以放的奇数和偶数的个数统计到odd[r][c]和even[r][c]中,矩阵就压缩成了n*m了!注意如果F[r+p*n][c+q*m]是个确定的数,如果是奇数,那么even[r][c]=0,反之odd[r][c]=0.
这样问题就转化成了求n×m的矩阵,每行和每列的和都是奇数的方案数!
接下来我们先预处理出每一行都是奇数和的状态的方案数cnt[i][mask],然后再进行DP,方程是dp[i][mask1^maks2]+=dp[i-1][mask1]*cnt[i][maks2],第i-1行的列状态数是mask1,第i行选取的行状态是mask2,那么形成的列状态就是mask1^maks2,最后的答案就是dp[n][(1<<m)-1],(1<<m)-1恰好表示每一列的状态都是奇数。这道题真是很赞,状态设计好巧妙~~,完全想不到啊!
代码:
typedef long long LL;
#define MOD 1000000007
LL odd[][], even[][];
LL dp[][ << ], cnt[][ << ];
class MagicalGirlLevelTwoDivOne
{
public:
int go(int num)
{
int ret = ;
while (num)
{
ret += num & ;
num >>= ;
}
return ret;
}
int theCount(vector <string> palette, int n, int m)
{
int x = palette.size(), y = palette[].size();
for (int i = ; i < n; i++)
for (int j = ; j < m; j++) odd[i][j] = even[i][j] = ;
for (int i = ; i < x; i++)
for (int j = ; j < y; j++)
{
if (palette[i][j] == '.')
{
odd[i % n][j % m] *= ;
odd[i % n][j % m] %= MOD;
even[i % n][j % m] *= ;
even[i % n][j % m] %= MOD;
}
else
{
int num = palette[i][j] - '';
if (num % == ) odd[i % n][j % m] = ;
else even[i % n][j % m] = ;
}
}
memset(cnt, , sizeof(cnt));
for (int i = ; i < n; i++)
for (int mask = ; mask < ( << m); mask++)
{
int tot = go(mask);
if (tot % == ) continue;
cnt[i][mask] = ;
for (int j = ; j < m; j++)
{
if (mask & ( << j))
cnt[i][mask] *= odd[i][j];
else cnt[i][mask] *= even[i][j];
cnt[i][mask] %= MOD;
}
}
memset(dp, , sizeof(dp));
dp[][] = ;
for (int i = ; i <= n; i++)
for (int mask1 = ; mask1 < ( << m); mask1++)
for (int mask2 = ; mask2 < ( << m); mask2++)
{
dp[i][mask1 ^ mask2] += (dp[i - ][mask1] * cnt[i - ][mask2])%MOD;
dp[i][mask1 ^ mask2] %= MOD;
}
return (int)dp[n][( << m) - ];
}
};
SRM 514 DIV1 500pt(DP)的更多相关文章
- SRM 511 DIV1 500pt(DP)
题目简述 给定n个数,两个人轮流取数,和之前两个人的取的数或起来,谁不能取数或者谁取到的数和之前的数或值为511谁输,问谁能够赢? 题解 刚开始的想法是直接搜,不过需要记录取过的值的状态,2^50显然 ...
- SRM 508 DIV1 500pt(DP)
题目简述 给定一个大小为 n的序列(n<=10)R,要求你计算序列A0, A1, ..., AN-1的数量,要求A序列满足A0 + A1 + ... + AN-1 = A0 | A1 | ... ...
- SRM 509 DIV1 500pt(DP)
题目简述 给定一个字符串,可以对其进行修改,删除,增加操作,相应的操作有对应的花费,要求你用最小的花费把字符串变为回文串 题目做法 先搞一遍floyed把各种操作的最小花费求出来,然后就是类似编辑距离 ...
- SRM 502 DIV1 500pt(DP)
题目简述 给定比赛时间T和n个题目,你可以在任意时间提交题目,每个题目有一个初始分数maxPoints[i],每个单位时间题目的分数将会减少pointsPerMinute[i],即如果在时间t解决了第 ...
- SRM 501 DIV1 500pt(DP)
题目简述 给定一个长度为n的序列,每个数值的范围为[-1,40],-1可以替换成0~40之间的数,要求你求出符合以下条件的序列有多少个? 1.每个数都是0~40之间的数 2.对于每一个数A[i],都需 ...
- SRM DIV1 500pt DP
SRM 501 DIV1 500pt SRM 502 DIV1 500pt SRM 508 DIV1 500pt SRM 509 DIV1 500pt SRM 511 DIV1 500pt SRM 5 ...
- SRM 358(1-250,500pt)
DIV1 250pt 题意:电视目前停留在第100台,有一个遥控器,可以向上或向下换台(需要按键一次),也可以按一些数字,然后直接跳到该台(需要按键次数等于数字数,不需要按确定键).但是,这个遥控一些 ...
- SRM 601(1-250pt,500pt)
DIV1 250pt 题意:有很多袋子,里面装有苹果和橘子(也可能没有),给出每个袋子里有多少个苹果,多少个橘子.如果每个袋子里含有水果的总数都不小于x个,则可以从每个袋子里都拿出x个水果(拿出苹果和 ...
- Topcoder SRM 643 Div1 250<peter_pan>
Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...
随机推荐
- 转response.sendRedirect()与request.getRequestDispatcher().forward()区别
JSP中response.sendRedirect()与request.getRequestDispatcher().forward(request,response)这两个对象都可以使页面跳转,但是 ...
- PHP工程师面临成长瓶颈
作为开发中应用最广泛的语言之一,PHP有着大量的粉丝,那么你是一名优秀的程序员吗?在进行自我修炼的同时,你是否想过面对各种各样的问题,我该如何突破自身的瓶颈,以便更好的发展呢?PHP工程师面临成长瓶颈 ...
- 在Hadoop伪分布式模式下安装Hive(derby,mysql)
我的Hadoop版本是1.2.0,mysql版本是5.6.12. 先介绍一下嵌入式derby模式: 1.下载/解压 在hive官网上选择要下载的版本,我选择的版本是hive-0.10.0. 下载好解压 ...
- 随机森林——Random Forests
[基础算法] Random Forests 2011 年 8 月 9 日 Random Forest(s),随机森林,又叫Random Trees[2][3],是一种由多棵决策树组合而成的联合预测模型 ...
- Objective-C命名编写规范
There are only two hard things in Computer Science: cache invalidation and naming things. 在计算机科学中只有两 ...
- IEDA常用设置
安装插件步骤省略,暂时不需要 IDEA菜单详解:基本有对应的快捷键或者是图标Help系列:Find Action:作用:快速新建文件,Ctrl + Shift + AHelp Topics:作用:帮助 ...
- ios8.3 编译 arm64版 openssl-1.0.2a
xcode是6.3版的,ios sdk 是8.3的, 到http://www.openssl.org/source/下载最新版本openssl-1.0.2a 解压后用文本编辑器打开configure文 ...
- unicode string和ansi string的转换函数及获取程序运行路径的代码
#pragma once#include <string> namespace stds { class tool { public: std::string ws2s(const std ...
- [反汇编练习] 160个CrackMe之007
[反汇编练习] 160个CrackMe之007. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...
- vim变ide
如果你稍微写过一点代码,就能知道“集成开发环境”(IDE)是多么的便利.不管是Java.C还是Python,当IDE会帮你检查语法.后台编译,或者自动导入你需要的库时,写代码就变得容易许多.另外,如果 ...