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*... ...
随机推荐
- Maven远程仓库
根据Apache Maven声明:"只有当在本地和中心仓库找不到所需的依赖文件,才会到远程仓库去下载". 当在Maven里声明了一个本地和中心仓库都没有的库文件时,Maven会停止 ...
- Lucas定理学习小记
(1)Lucas定理:p为素数,则有: (2)证明: n=(ak...a2,a1,a0)p = (ak...a2,a1)p*p + a0 = [n/p]*p+a0,m=[m/p]*p+b0其次,我们 ...
- uva12034Race
递推,组合. 考虑第一名有i个人,则f[n]=sum(C(n,i)*f[n-i]),递推即可.. #include<cstdio> #include<algorithm> #i ...
- LA 4329 (树状数组) Ping pong
第一次写树状数组,感觉那个lowbit位运算用的相当厉害. 因为-x相当于把x的二进制位取反然后整体再加上1,所以最右边的一个1以及末尾的0,取反加一以后不变. 比如1000取反是0111加一得到10 ...
- 面向函数范式编程(Functional programming)
函数编程(简称FP)不只代指Haskell Scala等之类的语言,还表示一种编程思维,软件思考方式,也称面向函数编程. 编程的本质是组合,组合的本质是范畴Category,而范畴是函数的组合. 首先 ...
- js 写成类的形式 js 静态变量 js方法 属性 json类
function ClassStudentList() { //[{"Cid":"0d","Students":[{"Sid&qu ...
- 用户输入 i. 检测常用手势(一)
参考: http://blog.csdn.net/qq418716640/article/details/8508973http://www.cnblogs.com/mengdd/p/3335508. ...
- Android中shape中的属性大全
---恢复内容开始--- <shape> <!-- 实心 --> <solid android:color="#ff9d77"/> <!- ...
- 最简单的基于FFMPEG的转码程序
本文介绍一个简单的基于FFmpeg的转码器.它可以将一种视频格式(包括封转格式和编码格式)转换为另一种视频格式.转码器在视音频编解码处理的程序中,属于一个比较复杂的东西.因为它结合了视频的解码和编码. ...
- .NET/ASP.NET Routing路由(深入解析路由系统架构原理)http://wangqingpei557.blog.51cto.com/1009349/1312422
阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模型的入口 4.ASP.NET Routing 路由对象模型的内部结构 4 ...