zoukankan      html  css  js  c++  java
  • NYOJ 980 格子刷油漆 动态规划

    这道题目状态转移方程比较复杂,刚开始以为没这么多情况,看了好多大牛的博客再加上与同学讨论才看懂,写下心得。

    因为起点不固定,所以我们一个一个来考虑,先从角上考虑,设三个数组来表示分别为D,A,Sum,分别表示为“从一个角开始然后回到同一列的对应位置的总个数”, “从一个角开始的总个数(包括回到对应位置和不回到对应位置)”, “表示总的个数”

    1. 当回到对应位置时: 

      D[1] = 1,D[n] = 2 * D[n-1];

      因为他可以有两种方式出去,最后再回来,如图(a), 图上是以右上角这个格子出发的,然后回到右下角这个格子,一共有两种方式出去。

    2. 不一定回到对应位置时,就是一个角的总个数:

      A[n] = D[n] + 2*A[n - 1] + 4 * A[n - 2];

      其中, D[n]表示回到对应位置的,而A[n-1]这种情况如图(b)所示,先上对面去,然后再接着向前走,所以还是两种方式出去,后面这种表示挨着走完两列,就是前面没有的这种情况,一共有两种走法,但是每种走法又有两种出去的方式,所以是4种,如下图(c)表示的,黑色(1,2两种)的和红色的(3,4两种)箭头方向。

      这只是其中一个角,因为只要n>2就有4个角,所以这个所有角的个数就是4*A[n];

    3.当从中间位置开始走时:

      假设从 i 开始走, 2*(2*D[i-1]*2*A[n-i] + 2*D[n-i]*2*A[i-1]),最后从2 - n-1 遍历一遍加起来

      假设从 i 开始走,显然不能直接往下走,否则无法遍历所有点,应当是先遍历左边(右边)所有点,然后回到相对的点,然后遍历右边(左边)的点。注意先遍历的时候,必须是采用“遍历全体格子后回到与之相对的格子”的走法,否则无法遍历出发点正下方的点,而后遍历则不受限制。所以先往左走的 i 之前的方法总数就是D[i - 1], 之后A[n - i],同理可以推先往右走的。

    附AC代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 const int N = 1005;
     5 const long long mod = 1000000007;
     6 long long D[N], A[N], Sum[N];//D数组表示从一个角出发,最后回到出发点的同一列所对应的那个格子的总个数,
     7 //A数组表示所有一个角出发的总个数,Sum表示总的个数
     8 int main()
     9 {
    10     D[1] = 1;
    11     A[1] = 1;
    12     A[2] = 6;//初始条件,从一个角开始所有的总数
    13     Sum[1] = 2;//总数
    14     Sum[2] = 24;
    15     for (int i = 2; i < N; i++)
    16         D[i] = D[i - 1] * 2 % mod;
    17     for (int i = 3; i < N; i++)
    18         A[i] = (D[i] + 2 * A[i - 1] + 4 * A[i - 2]) % mod;
    19     for (int i = 3; i < N; i++)
    20     {
    21         Sum[i] = 4 * A[i] % mod;
    22         for (int k = 2; k < i; k++)
    23             Sum[i] = (Sum[i] + 8 * D[k - 1] * A[i - k] % mod + 8 * D[i - k] * A[k - 1] % mod) % mod;
    24     }
    25     int n;
    26     while (cin >> n)
    27     {
    28         cout << Sum[n] << endl;
    29     }
    30 
    31     return 0;
    32 }
    View Code
  • 相关阅读:
    Android视图控件架构分析之View、ViewGroup
    JAVA多线程编程——JAVA内存模型
    开源CMS系统Moodle对比中国本土化开源在线教育平台EduSoho
    Android系统Binder机制学习总结
    Android中一个关于ListView的奇怪问题
    判断分数区间(优良以及未及格)
    js求三个数的最大值运算
    年月日时间选择
    js单击时页面的弹出
    margin与padding
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4361113.html
Copyright © 2011-2022 走看看