• XTU OJ 1175 学习笔记


    1. #include
    2. using namespace std;
    3. typedef long long LL;
    4. const int N=50;
    5. LL a[N][5];
    6. void initialize()
    7. {
    8. a[1][1]=a[1][2]=a[1][3]=a[1][4]=1;
    9. for(int i=2;i<=45;i++)
    10. {
    11. a[i][1]=a[i-1][2]+a[i-1][3];
    12. a[i][2]=a[i-1][1]+a[i-1][3]+a[i-1][4];
    13. a[i][3]=a[i-1][1]+a[i-1][2]+a[i-1][4];
    14. a[i][4]=a[i-1][2]+a[i-1][3];
    15. }
    16. }
    17. int main()
    18. {
    19. initialize();
    20. int T;
    21. scanf("%d",&T);
    22. while(T--)
    23. {
    24. int n;
    25. scanf("%d",&n);
    26. LL ans=0;
    27. ans=a[n][1]+a[n][2]+a[n][3]+a[n][4];
    28. //printf("%I64d\n",ans);
    29. cout<
    30. }
    31. return 0;
    32. }

    参考题解: 

    1.题解1

    2.题解2

    根据题意,1旁边只能是2/3,2旁边只能是1/3/4,3旁边只能是1/2/4,4旁边只能是2/3,首先看一下数据范围,2或者3的45次方,2^45/3^45,这个超过了2^31,超过了int的数据范围,所以我们需要使用long long

    我们使用一个数组来存储数字。第一个位置可以存1/2/3/4,有四种情况,假设第一个位置存的是1/4,那么第二个位置就只能存2/3,只有两种情况,假设第一个位置存的是2/3,第二个位置有三个数字可以选择。那么我们到底应该怎么考虑这个问题?

    (笔者也是初学者,所以如有错误欢迎大佬指正)动态规划(dp)来解决这道题, 动态规划最关键的就是建立状态转移方程

    动态规划算法把原问题视作若干个重叠子问题的逐层递进,每个子问题的求解过程都构成一个“阶段”。在完成前一个阶段的计算后,动态规划才会执行下一阶段的计算。

    状态转移方程就是这个,

    1. a[1][1]=a[1][2]=a[1][3]=a[1][4]=1;
    2. for(int i=2;i<=45;i++)
    3. {
    4. a[i][1]=a[i-1][2]+a[i-1][3];
    5. a[i][2]=a[i-1][1]+a[i-1][3]+a[i-1][4];
    6. a[i][3]=a[i-1][1]+a[i-1][2]+a[i-1][4];
    7. a[i][4]=a[i-1][2]+a[i-1][3];
    8. }

    从第一个元素开始处理,每一次循环,前面的数据是已经被处理过的数据(被计算过),这一点和前缀和的思路有点儿类似。循环结束,所有元素都被处理过了。

    输出64位整数,使用%I64d 

     

  • 相关阅读:
    三网话费余额查询的API系统 基于thinkphp6.0框架
    Viper FTP Mac/ftp管理工具
    鲲鹏devkit性能分析工具介绍(四)
    在 Vue3 项目中如何关闭 ESLint
    论文阅读之Reasoning Implicit Sentiment with Chain-of-Thought Prompting
    ipv6一致性-NDP测试
    小景的工具使用--Java诊断工具Arthas的使用说明
    flask要点与坑
    Linux常用命令
    Nignx部署前端页面
  • 原文地址:https://blog.csdn.net/L3102250566/article/details/134393152