HDU 2045:不容易系列之(3)—— LELE的RPG难题(动态规划)

一、原题链接

Problem - 2045 (hdu.edu.cn)

二、题面

c++ 复制代码
人称"AC女之杀手"的超级偶像LELE最近忽然玩起了深沉,这可急坏了众多"Cole"(LELE的粉丝,即"可乐"),经过多方打探,某资深Cole终于知道了原因,原来,LELE最近研究起了著名的RPG难题:

有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法.

以上就是著名的RPG难题.

如果你是Cole,我想你一定会想尽办法帮助LELE解决这个问题的;如果不是,看在众多漂亮的痛不欲生的Cole女的面子上,你也不会袖手旁观吧?

三、示例

  1. 输入

    复制代码
      输入数据包含多个测试实例,每个测试实例占一行,由一个整数N组成,(0<n<=50)。
    复制代码
      1
      2
  2. 输出

    复制代码
      对于每个测试实例,请输出全部的满足要求的涂法,每个实例的输出占一行。
    复制代码
      3
      6

五、思路

  1. 动态规划使用条件

    • 无后效性

      • 将集合的表达定义为arr[n]:n个方格的有效排列数

        后效性:对于一个n格的有效排列,第n格的颜色不单 要求与第n-1格不同,还要求与第一格不同

      • 将集合的表达定义为arr[n][i][j]:n个方格 第一个颜色为i最后一个颜色为j,故问题转换为了求n格方格且相邻两个颜色不同的可能数 ,在输出结果时仅输出两个不同颜色的结果之

        注:增加维度本质还是分类讨论

    • 最优子结构:由上,显然对于目标问题n个相邻颜色不同的方格排列,有子问题 n-1个相邻颜色不同的方格排列必然成立

    • 重复子问题:无

  2. 动态规划模型构建

    • 集合表达

      ans[55][3][3]

      • 第一维表示方格数
      • 第二维表示起始颜色
      • 第三维表示结束颜色
    • 递推式:n个方格的排列可由n-1个方格推得

      c++ 复制代码
      for(int i=2;i<=50;i++){
          for(int j=0;j<3;j++){
              ans[i][j][j]=ans[i-1][j][(j+1)%3]+ans[i-1][j][(j+2)%3];
              ans[i][j][(j+1)%3]=ans[i-1][j][j]+ans[i-1][j][(j+2)%3];
              ans[i][j][(j+2)%3]=ans[i-1][j][j]+ans[i-1][j][(j+1)%3];
          }
      }
    • 初值确定:由递推式可知,只需知道1个方格的排列

      c++ 复制代码
      for(int i=0;i<3;i++){
          ans[1][i][i]=1;
      }

六、code

c++ 复制代码
#include <bits/stdc++.h>

#define PI 3.1415927

using namespace std;
typedef long long ll;

int main()
{
    ll n,ans[55][3][3];
    memset(ans,0,55*3*3*sizeof(ll));
    //求n个相邻颜色不同的方格排列
    for(int i=0;i<3;i++){
        ans[1][i][i]=1;
    }
    for(int i=2;i<=50;i++){
        for(int j=0;j<3;j++){
           ans[i][j][j]=ans[i-1][j][(j+1)%3]+ans[i-1][j][(j+2)%3];
           ans[i][j][(j+1)%3]=ans[i-1][j][j]+ans[i-1][j][(j+2)%3];
           ans[i][j][(j+2)%3]=ans[i-1][j][j]+ans[i-1][j][(j+1)%3];
        }
    }
    while(cin >> n){
        //求n个相邻颜色不同且收尾颜色不同的方格排列
        ll num=0;
        for(int i=0;i<3;i++){
            if(n==1){
                num+=ans[n][i][i];
            }
            num+=ans[n][i][(i+1)%3];
            num+=ans[n][i][(i+2)%3];
        }
        cout << num << endl;
    }
    return 0;
}
相关推荐
学究天人34 分钟前
数学公理体系大全:第一章 命题逻辑:真值之舞
人工智能·算法·机器学习·数学建模·动态规划·图论·抽象代数
旖-旎2 小时前
《LeetCode 978 最长湍流子数组 || LeetCode 139 单词拆分》
c++·算法·leetcode·动态规划
学究天人3 小时前
数学公理体系大全:Comprehensive Collection of Mathematical Axiom Systems(补充卷9)
人工智能·线性代数·算法·数学建模·动态规划·原型模式·抽象代数
初学者,亦行者4 小时前
算法设计与分析:动态规划 - TSP问题和0-1背包问题
c++·算法·动态规划
学究天人4 小时前
数学公理体系大全:第四章 ZFC公理的形式化与构造演算
线性代数·数学建模·矩阵·动态规划·图论·抽象代数·拓扑学
旖-旎20 小时前
《LeetCode 53 最大子数组和 || LeetCode 918 环形子数组的最大和》
c++·算法·leetcode·动态规划
c238561 天前
《动态规划:从“傻傻穷举”到“过目不忘”的修仙之路》
c++·算法·动态规划
学究天人1 天前
数学公理体系大全:Comprehensive Collection of Mathematical Axiom Systems(卷7)
线性代数·矩阵·动态规划·概率论·图论·抽象代数·拓扑学
学究天人1 天前
数学公理体系大全:Comprehensive Collection of Mathematical Axiom Systems(卷6)
网络·算法·数学建模·动态规划·几何学·图论·拓扑学
wabs6661 天前
关于动态规划【力扣72.编辑距离的思考】
算法·leetcode·动态规划