Step1 Problem
给你 5 个由 01 组成的长度为 100 的字符串。
让你求选 5 个 1 且 1 不能再同一列的方案数
Step2 Ideas:
学习博客
dp[i][j]:到了第 j 列,选了 i 个 1 且第 i 个 1 对应的列 大于 第 i-1 个 1 对应的列的方案数
结果等于 = 5 个字符串全排列后的 sum{ dp[5][100] }.
Step3 Code:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
const int MOD = 1e9+7;
const ll CT = 531192758;
char s[6][150];
ll dp[6][150], ans;
void permuDP(int u)
{
if(u == 5)//对于每一种排列求 dp[5][100]
{
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= 100; i++)
{
dp[1][i] = dp[1][i-1];
if(s[1][i] == '1') dp[1][i]++;
}
for(int k = 2; k <= 5; k++)
{
for(int i = 1; i <= 100; i++)
{
dp[k][i] = dp[k][i-1];
if(s[k][i] == '1') dp[k][i] += dp[k-1][i-1]; dp[k][i] %= MOD;
}
}
ans += dp[5][100]; ans %= MOD;
}
for(int i = u; i <= 5; i++)//枚举全排列
{
swap(s[u], s[i]);
permuDP(u+1);
swap(s[u], s[i]);
}
}
int main()
{
while(~scanf("%s", s[1]+1))
{
ans = 0;
for(int i = 2; i <= 5; i++)
scanf("%s", s[i]+1);
permuDP(1);
printf("%lld\n", (ans*CT)%MOD);
}
return 0;
}