1 条题解

  • 0
    @ 2026-1-30 21:54:27

    当看到“求方案总数”,“且当前决策只受上一个决策影响”的问题时,脑子里应该自动浮现这个框架:

    long long dfs(int index, int last_state) {
    // 1. 边界:任务完成了,算作 1 种有效方案
    if (index > total_steps) return 1;
    // 2. 累加器
    long long res = 0;
    // 3. 遍历当前所有可能的选择
    for (int choice : all_possible_choices) {
    // 4. 判断当前选择是否符合规则(依赖 last_state)
    if (is_legal(choice, last_state)) {
    // 5. 递归下去,把子问题的结果加起来
    res += dfs(index + 1, choice);
    }
    }
    return res;
    }
    

    ​这种 DFS 其实就是自顶向下的动态规划。 dfs(col, prev_row)实际上就是在计算dp[col][prev_row]。 如果你在 DFS 里加上一个数组memo[col][prev_row]来记录已经计算过的结果(记忆化搜索),它就和递推形式的 DP 完全等价了。

    一句话口诀: 按序搜,传状态,过边界,返一,合分求总数。

    对于本题,传入的参数为当前的列号和上一行的行号,因为皇后也和上一个皇后在同一行或上下两行,所以要有上一行来作为参数 在主循环中主要是根据initial[i]即是否已经放了皇后来判断方案数

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    int initial[11];
    // col:当前列数
    // prev_row:上一列皇后所在的行号
    long long dfs(int col, int prev_row) {
        // 递归边界:所有列都放好了
        if(col>n) return 1;
        long long count=0;
        // 如果当前列已经有预设的皇后
        if (initial[col]!=0) {
            int curr_row = initial[col];
            // 如果是第一列,或者与上一列行数差不超过1
            if (col==1||abs(curr_row-prev_row) <= 1) {
                count+=dfs(col+1,curr_row);
            }
        } 
        // 如果当前列没有预设,需要尝试放置
        else {
            if (col==1){
                // 第一列可以放任何位置
                for(int r=1;r<=n;r++){
                    count+=dfs(col+1,r);
                }
            } else {
                // 非第一列,只能放在上一列行号的[-1,0,1]范围内
                for(int r=prev_row-1;r<=prev_row+1;r++){
                    if(r>=1&&r<=n) { //确保不越界
                        count+=dfs(col+1,r);
                    }
                }
            }
        }
        return count;
    }
    int main() {
        while(cin>>n&&n!=0){
            for(int i=1;i<=n;i++){
                cin>>initial[i];
            }
            cout<<dfs(1,0)<<endl; //从第一列开始搜,初始行可以设为任意值
        }
        return 0;
    }
    

    信息

    ID
    975
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    4
    已通过
    2
    上传者