• 小国王(目标状态优化版)—— 状态压缩DP


     在 n×n 的棋盘上放 k 个国王,国王可攻击相邻的 8 个格子,求使它们无法互相攻击的方案总数。

    输入格式

    共一行,包含两个整数 n 和 k。

    输出格式

    共一行,表示方案总数,若不能够放置则输出0。

    数据范围

    1≤n≤10,
    0≤k≤n^2

    输入样例:

    3 2
    

    输出样例:

    16

    思路:

    f[i][j][k]:表示前i行放置了j个国王,且第i行的状态是k        属性:cnt

    首先考虑当前这一行,找到当前这一行所有的合法状态(即状态的纵坐标不相邻),以及合法状态的合法转移状态(因为当前这一行的状态肯定是上一行转移过来的,所以只需要考虑上一行的状态。 那么上一行什么样的状态才能转移成当前的状态?由题意发现上一行状态与当前行状态的纵坐标不能相邻上下不能相邻,左右也不能相邻)以便于状态转移计算。

    状态表示:

    f[i][j][k]:表示前i行放置了j个国王,且第i行的状态是k        

    属性:cnt

    状态计算:

    f[i][j][k] +=  f[i-1][j-cnt[state]][state]

    初始状态:

    f[0][0][0]

    目标状态:

    f[n][k][legal]         //legal为所有的合法状态     

    解决代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. using namespace std;
    7. typedef long long LL;
    8. const int N = 12, M = 1 << N, C = N * N;
    9. int n, m, k;
    10. LL f[N][C][M]; //f[i][j][k]:表示前i行放置了j个国王,且第i行的状态是k 属性:cnt
    11. int cnt[M]; //用来存储每个合法状态中有多少个国王
    12. vector<int> legal; //存放合法状态数组
    13. vector<int> trans[M]; //存放合法状态的合法转移状态
    14. bool check(int state) //检查纵坐标是否相邻
    15. {
    16. return !(state&state>>1);
    17. }
    18. int count(int state)
    19. {
    20. int cnt = 0;
    21. for(int i=0;iif(state>>i&1) cnt++;
    22. return cnt;
    23. }
    24. int main()
    25. {
    26. cin>>n>>k;
    27. //预处理所有状态
    28. for(int i=0;i<1<
    29. //检查当前状态是否合法
    30. if(check(i))
    31. {
    32. legal.push_back(i);
    33. cnt[i] = count(i);
    34. }
    35. //预处理所有合法状态的合法转移状态
    36. for(auto i:legal)
    37. for(auto j:legal)
    38. if(!(i&j)&&check(i|j)) //上下不相邻且左右不相邻
    39. trans[i].push_back(j);
    40. f[0][0][0] = 1;
    41. for(int i=1;i<=n+1;i++)
    42. for(int j=0;j<=k;j++)
    43. for(auto st : legal)
    44. for(auto tt : trans[st])
    45. if(j-cnt[st]>=0)
    46. f[i][j][st] += f[i-1][j-cnt[st]][tt];
    47. cout<1][k][0];
    48. return 0;
    49. }

  • 相关阅读:
    基于SSM农产品商城系统
    < Linux > 进度条小程序 + git三板斧
    【Leetcode HOT100】最长递增子序列 c++
    随手记录第三话 --你见过哪些神乎其乎的存储方式?
    二、集成学习:Boosting 之 AdaBoost_分类问题
    红队专题-开源漏扫-巡风xunfeng源码剖析与应用
    leetcode283移动零
    深入探索 Django Rest Framework
    Layui 表单设计器
    DataTable导出Excel
  • 原文地址:https://blog.csdn.net/m0_56511205/article/details/128022730