uva10401

来源:互联网 发布:js首页下拉列 编辑:程序博客网 时间:2024/06/03 18:34

题目大意:
给出一个字符串,?表示皇后可以放在这一列的任何位置,如果是数字或者字母表示可以只能放在相应的行。问最多可以有多少种放法。

思路:
dp[i][j]表示皇后放在(i,j)最多可以有多少种放法。从第一列往后面去递推。
k表示除了与皇后相近的那三行外,dp[i][j] += dp[k][j - 1]。结合了前j - 1列。

代码:

#include <iostream>using namespace std;#include <cstring>#include <stdio.h>#include <algorithm>#include <cmath>const int N = 30;char s[N];int vis[N];long long dp[N][N];long long ans;int main() {    while(scanf("%s",s + 1) != EOF) {        ans = 0;        //cout << s + 1 << endl;    //  memset(dp,0,sizeof(dp));        memset(vis,0,sizeof(vis));        memset(dp,0,sizeof(dp));        int len = strlen(s + 1);     for (int i = 1; i <= len; i++) {            if (s[i] >= '1' && s[i] <= '9') {                vis[i] = s[i] - '0';            } else if (s[i] >= 'A' && s[i] <= 'F') {                vis[i] = s[i] - 'A' + 10;            }        }    /*  for(int i = 1; i <= len; i++)            cout << vis[i] <<endl;*/        //cout << endl;           if (vis[1]) {            dp[vis[1]][1] = 1;        } else {            for (int i = 1; i <= len; i++) {                dp[i][1] = 1;            }        }    //  cout << endl;        for(int i = 2; i <= len; i++) {            //cout << endl;            if (vis[i]) {                for (int k = 1; k <= len; k++) {                    if (abs(vis[i] - k) > 1) {                        dp[vis[i]][i] += dp[k][i - 1];                    }                }                   }            else {                //cout << vis[i] <<endl;                for(int j = 1; j <= len; j++) {                    for(int k = 1; k <= len; k++) {                        if(abs(j - k) > 1)                             dp[j][i] += dp[k][i - 1];                    }                }            }        }        //cout << endl;        for(int i = 1; i <= len; i++)            ans += dp[i][len];        printf("%lld\n",ans);    }    return 0;}
0 0