• 算法设计与分析-10304 平面域着色


     小技巧,当题目问到方案数时,此题目几乎可以确定是动态规划类题目,动态规划也是用递归的思想来考虑如和实现分治(将大问题变小),读者可以尝试将递归代码改写成递推代码(动态规划)。

    解题思路:递归基础题,难点在于圆环。观察D1和Dn,由于环相邻,它们颜色必不相同。此时如果Dn-1和D1颜色相同,那么Dn的颜色共有K-1中选择,且Dn的颜色无论是什么都不会影响到D2......Dn-2。那么我们将D1DnDn-1想象成是一个域,此时问题就从规模n变成了规模n-2。

     另一种情况Dn-1和D1颜色不同,此时Dn就 只有K-2中颜色选择,当然,无论它选哪一种颜色,对其他位置都不会有任何影响。此时我们可以认为Dn-1是最后一个元素,认为Dn-1可以与D1相邻(颜色不同)。此时问题规模变为n-1。

    因此递推公式为 f(n)=(k-1)*f(n-2)+(k-2)*f(n-1)

    还有一些无法填充特殊情况必须要考虑进去,

    (1)n>1&&k==1 颜色不足以填充,答案0;

    (2)n%2==1&&k==2 奇数个格子只有2中颜色,那么D1和Dn会同色;

    递归结束条件也有三种情况,请阅读代码。(友情提示:本代码已开启防抄袭模式,请勿复制粘贴)

    1. #include <bits/stdc++.h>
    2. typedef long long ll;
    3. using namespace std;
    4. long long f(int n,int k)
    5. {
    6. if(n==1)
    7. return k;
    8. else if(n==2)
    9. return k*(k-1);
    10. else if(n==3)
    11. return k*(k-1)*(k-2);
    12. return (k-1)*f(n-2,k)+(k-2)*f(n-1,k);
    13. }
    14. int main()
    15. {
    16. ios::sync_with_stdio(0),cin.tie(0);
    17. int i,j,n,k;
    18. cin>>n>>k;
    19. if(n>1&&k<1||n%2=1&&k==2)
    20. {
    21. cout<<0;
    22. return 0;
    23. }
    24. cout<<f(n,k);
    25. return 0;
    26. }

  • 相关阅读:
    TypeScript环境安装
    4、MFC:菜单栏、工具栏与状态栏
    前端重新部署如何使用WebWorker优雅地通知用户刷新网页?
    数据结构学习笔记——基数排序和排序算法总结
    MySQL读写分离
    SpringBoot的简单介绍
    python图像处理 ——图像分块
    vue.config.js配置proxy代理产生404错误的原因
    基本类型包装类
    Java并发 | 08.[方法] 线程的生命周期及常用的方法
  • 原文地址:https://blog.csdn.net/sigd/article/details/126898002