这道题目和算法入门经典蓝色的的386页的差不多,不过难度深了一点。
然后这道题目写了6个小时TAT,关键的原因在于判断向上摆放和向左摆放的时候if条件中多了一个atlas[i][j] = 1,然后输出就一直都是0。说明一下原因吧,首先因为当atlas[i][j] = 0的时候我们将结果保存了,那么当i变成i + 1的时候,在进行往上面摆放的话,这个时候的状态转移也是相当于保存了值,所以就是一直保存下去,但是如果再这个if中多了一个atlas[i][j] = 0的话,那就没有保存值,就相当于这个状态是0了,那么往后面也都是0,所以一定要清楚是什么状态
#include<cstdio> #include<algorithm> #include<cstring> #include<string> using namespace std; const int maxn = 100; const int maxm = 10 + 1; const int mod = 1000000007; int n, m, c, d; int cur; int atlas[maxn][maxm]; int dp[2][1 << maxm][25]; void init(){ memset(atlas, -1, sizeof(atlas)); memset(dp, 0, sizeof(dp)); char ch[maxm + 1]; for (int i = 0; i < n; i++){ memset(ch, 0, sizeof(ch)); scanf("%s", ch); for (int j = 0; ch[j] != '\0'; j++){ atlas[i][j] = ch[j] - '0'; } } /*for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++){ printf("%d%c", atlas[i][j], j == m - 1 ? '\n' : ' '); } }*/ } void update(int a, int b, int flag, int g){ if (b & (1 << m)) if (flag) dp[cur][b ^ (1 << m)][g + 1] = (dp[cur][b ^ (1 << m)][g + 1] + dp[1 - cur][a][g]) % mod; else dp[cur][b ^ (1 << m)][g] = (dp[cur][b ^ (1 << m)][g] + dp[1 - cur][a][g]) % mod; } void work(){ cur = 0; dp[0][(1 << m) - 1][0] = 1; for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++){ cur ^= 1; memset(dp[cur], 0, sizeof(dp[cur])); if (atlas[i][j] == 0){ for (int g = 0; g <= d; g++){ for (int k = 0; k < (1 << m); k++){ update(k, (k << 1) ^ 1 , 0, g); } } } else { for (int g = 0; g <= d; g++){ for (int k = 0; k < (1 << m); k++){ update(k, (k << 1) ^ 1, 1, g); update(k, k << 1, 0, g); if (i && !(k & (1 << m - 1))){ update(k, ((k << 1) ^ (1 << m) ^ 1), 0, g); } if (j && !(k & 1)){ update(k, ((k << 1) ^ 3), 0, g); } } } } } } long long res = 0; for (int i = c; i <= d; i++) res = (res + dp[cur][(1 << m) - 1][i]) % mod; printf("%lld\n", res); } int main(){ while (scanf("%d%d%d%d", &n, &m, &c, &d) != EOF){ init(); work(); } return 0; } </string></cstring></algorithm></cstdio>