在线编程在线课堂在线测评Anycodes在线编程

编程论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

How to use bs4??
本帖最后由 carry0987 于
Double Queue 问题描述 : The new founded Balkan Investment Group Bank (
John 问题描述 : Little John is playing very funny game
linux-command Linux命令大全搜索工具,内容包含Linux命令
Coati 是一款跨平台的代码查看工具,适用于 C/C++ 和 Java。商业软件。特性:1. 索引
系统可承载海量并发,消息收发确认机制 保障消息必达 系统采用动态智
全平台视频监控,支持安卓苹果以及pcweb,支持海康大华等主流dvr,全部源码以及文档 单聊、群聊、商
如何访问类的私有属性? 下面以 TPathData 为例,
问题:从 XE4 以来,Firemonkey 曲线绘图在移动平台不平滑的问题一直令人诟病,提交到官方的 QC 也是族繁不及备载,官方似乎有意的
操作数据库(RODBC)   odbcConnect(dsn, uid="", p
数据模式:mode函数显示任何对象的模式。常见的单个的
系统可承载海量并发,消息收发确认机制 保障消息必达 系统采用动态智
RabbitMQ与PHP(一) 项
Iease团队扩编预备中,盼望能有Ruby或者java工程师加盟。全职兼职都可以。有爱好的伴侣请与我接洽。 邮件:i
ruby 怎么设置装备摆设GTK2,求教指导下!
#include #include #include #include using namespace std; int main() {
标题如图所示: 有n盏灯,编号1~n。一开端灯都是关着的
成熟的消息收发确认机制,支持万人大群 支持开发自定义的消息sdk接口,扩展性超强 支持单/
成熟的消息收发确认机制,支持万人大群 支持开发自定义的消息sdk接口,扩展性超强 支持单/
1. 注意列表和集合的区别 set 列表表现形式: list_1
Ajax   Ajax即“Asynchronous Javascript And
大师好,我比来在做布谷鸟优
分辨提取A和B图像Harris角点,接下来须要对

[HDU杭电] HDU 4758-Walk Through Squares-动态规划-[解题报告]HOJ

[复制链接]
发表于 2016-3-30 22:15:41 | 显示全部楼层 |阅读模式
Walk Through Squares


问题描述 :

  On the beaming day of 60th anniversary of NJUST, as a military college which was Second Artillery Academy of Harbin Military Engineering Institute before, queue phalanx is a special landscape.
  
  Here is a M*N rectangle, and this one can be divided into M*N squares which are of the same size. As shown in the figure below:
  01–02–03–04
  ||  ||  ||  ||
  05–06–07–08
  ||  ||  ||  ||
  09–10–11–12
  Consequently, we have (M+1)*(N+1) nodes, which are all connected to their adjacent nodes. And actual queue phalanx will go along the edges.
  The ID of the first node,the one in top-left corner,is 1. And the ID increases line by line first ,and then by column in turn ,as shown in the figure above.
  For every node,there are two viable paths:
  (1)go downward, indicated by ‘D’;
  (2)go right, indicated by ‘R’;
  The current mission is that, each queue phalanx has to walk from the left-top node No.1 to the right-bottom node whose id is (M+1)*(N+1).
    In order to make a more aesthetic marching, each queue phalanx has to conduct two necessary actions. Let’s define the action:
  An action is started from a node to go for a specified travel mode.
  So, two actions must show up in the way from 1 to (M+1)*(N+1).  For example, as to a 3*2 rectangle, figure below:
    01–02–03–04
    ||  ||  ||  ||
    05–06–07–08
    ||  ||  ||  ||
    09–10–11–12
  Assume that the two actions are (1)RRD  (2)DDR  As a result , there is only one way : RRDDR. Briefly, you can not find another sequence containing these two strings at the same time.
  If given the N, M and two actions, can you calculate the total ways of walking from node No.1 to the right-bottom node ?
输入:
  The first line contains a number T,(T is about 100, including 90 small test cases and 10 large ones) denoting the number of the test cases.
  For each test cases,the first line contains two positive integers M and N(For large test cases,1<=M,N<=100, and for small ones 1<=M,N<=40). M denotes the row number and N denotes the column number.
  The next two lines each contains a string which contains only ‘R’ and ‘D’. The length of string will not exceed 100. We ensure there are no empty strings and the two strings are different.
输出:
  The first line contains a number T,(T is about 100, including 90 small test cases and 10 large ones) denoting the number of the test cases.
  For each test cases,the first line contains two positive integers M and N(For large test cases,1<=M,N<=100, and for small ones 1<=M,N<=40). M denotes the row number and N denotes the column number.
  The next two lines each contains a string which contains only ‘R’ and ‘D’. The length of string will not exceed 100. We ensure there are no empty strings and the two strings are different.
样例输入:

  1. 2
  2. 3 2
  3. RRD
  4. DDR
  5. 3 2
  6. R
  7. D
复制代码
样例输出:

  1. 1
  2. 10
复制代码
           AC自动机&#43;DP。想了很久都没想出来。。。据说是一道很模板的自动机dp。。。

Walk Through Squares

Walk Through Squares
原来自动机还可以这么跑啊。。。我们先用两个字符串建自动机,然后就是建一个满足能够从左上角到右下角的新串,这样我们直接从自动机中跑出一个满足题意的串就可以了,(貌似需要建新串的AC&#43;DP都需要这么搞啊!)可以利用chd数组去递推得到状态的种数。这里我们用dp[
i ][ j ][ k ][ s ]表示当字符的位置为在矩阵中位置为(i, j)时,及向右走了 i 次,向下走了 j 次,时到达自动机上下标为k 的节点时状态为 s (1表示有串1,2表示有串2,3表示两个串都有)的种数。
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <sstream>
  4. #include <cstdlib>
  5. #include <climits>
  6. #include <cstring>
  7. #include <cstdio>
  8. #include <string>
  9. #include <vector>
  10. #include <cctype>
  11. #include <queue>
  12. #include <cmath>
  13. #include <set>
  14. #include <map>
  15. #define CLR(a, b) memset(a, b, sizeof(a))

  16. using namespace std;
  17. typedef long long LL;

  18. const int MAX_NODE = 110 * 2;
  19. const int MOD = 1000000007;
  20. const int CHILD_NUM = 2;
  21. const int N = 110;

  22. class ACAutomaton
  23. {
  24. private:
  25.     int chd[MAX_NODE][CHILD_NUM];
  26.     int dp[2][N][MAX_NODE][4];
  27.     int fail[MAX_NODE];
  28.     int val[MAX_NODE];
  29.     int Q[MAX_NODE];
  30.     int ID[128];
  31.     int sz;
  32. public:
  33.     void Initialize()
  34.     {
  35.         fail[0] = 0;
  36.         ID['R'] = 0;
  37.         ID['D'] = 1;
  38.     }
  39.     void Reset()
  40.     {
  41.         CLR(chd[0] , 0);
  42.         CLR(val, 0);
  43.         sz = 1;
  44.     }
  45.     void Insert(char *a, int hav)
  46.     {
  47.         int p = 0;
  48.         for ( ; *a ; a &#43;&#43;)
  49.         {
  50.             int c = ID[*a];
  51.             if (!chd[p][c])
  52.             {
  53.                 memset(chd[sz] , 0 , sizeof(chd[sz]));
  54.                 chd[p][c] = sz &#43;&#43;;
  55.             }
  56.             p = chd[p][c];
  57.         }
  58.         val[p] |= hav;
  59.     }
  60.     void Construct()
  61.     {
  62.         int *s = Q , *e = Q;
  63.         for (int i = 0 ; i < CHILD_NUM ; i &#43;&#43;)
  64.         {
  65.             if (chd[0][i])
  66.             {
  67.                 fail[chd[0][i]] = 0;
  68.                 *e &#43;&#43; = chd[0][i];
  69.             }
  70.         }
  71.         while (s != e)
  72.         {
  73.             int u = *s&#43;&#43;;
  74.             for (int i = 0 ; i < CHILD_NUM ; i &#43;&#43;)
  75.             {
  76.                 int &v = chd[u][i];
  77.                 if (v)
  78.                 {
  79.                     *e &#43;&#43; = v;
  80.                     fail[v] = chd[fail[u]][i];
  81.                     val[v] |= val[fail[v]];
  82.                 }
  83.                 else
  84.                 {
  85.                     v = chd[fail[u]][i];
  86.                 }
  87.             }
  88.         }
  89.     }
  90.     int Work(int n, int m)
  91.     {
  92.         //最好手动初始化dp数组,不然如果没有用滚动数组的话会超时。
  93.         for(int j = 0; j <= m; j &#43;&#43;)
  94.                 for(int k = 0; k < sz; k &#43;&#43;)
  95.                     for(int s = 0; s < 4; s &#43;&#43;)
  96.                         dp[0][j][k][s] = 0;
  97.         dp[0][0][0][0] = 1;
  98.         for(int i = 0; i <= n; i &#43;&#43;)
  99.         {
  100.             for(int j = 0; j <= m; j &#43;&#43;)
  101.                 for(int k = 0; k < sz; k &#43;&#43;)
  102.                     for(int s = 0; s < 4; s &#43;&#43;)
  103.                         dp[(i &#43; 1) & 1][j][k][s] = 0;
  104.             for(int j = 0; j <= m; j &#43;&#43;)
  105.                 for(int k = 0; k < sz; k &#43;&#43;)
  106.                     for(int s = 0; s < 4; s &#43;&#43;)
  107.                     {
  108.                         if(i < n)
  109.                         {
  110.                             int next = chd[k][0];
  111.                             int tmp = s | val[next];
  112.                             dp[(i &#43; 1) & 1][j][next][tmp] &#43;= dp[i & 1][j][k][s];
  113.                             dp[(i &#43; 1) & 1][j][next][tmp] %= MOD;
  114.                         }
  115.                         if(j < m)
  116.                         {
  117.                             int next = chd[k][1];
  118.                             int tmp = s | val[next];
  119.                             dp[i & 1][j &#43; 1][next][tmp] &#43;= dp[i & 1][j][k][s];
  120.                             dp[i & 1][j &#43; 1][next][tmp] %= MOD;
  121.                         }
  122.                     }
  123.         }
  124.         int ret = 0;
  125.         for(int i = 0; i < sz;i &#43;&#43;)
  126.         {
  127.             ret = (ret &#43; dp[n & 1][m][i][3]) % MOD;
  128.         }
  129.         return ret;
  130.     }
  131. } AC;

  132. int main()
  133. {
  134.     //freopen("input.txt", "r", stdin);
  135.     AC.Initialize();
  136.     int n, t, m;
  137.     scanf("%d", &t);
  138.     while (t --)
  139.     {
  140.         AC.Reset();
  141.         scanf("%d%d", &n, &m);
  142.         for (int i = 1 ; i <= 2 ; i &#43;&#43;)
  143.         {
  144.             char temp[N];
  145.             scanf("%s", temp);
  146.             AC.Insert(temp, i);
  147.         }
  148.         AC.Construct();
  149.         printf("%d\n", AC.Work(n, m));
  150.     }
  151.     return 0;
  152. }
复制代码
参考:http://blog.csdn.net/ok_again/article/details/12448979
在线编程(http://www.anycodes.cn)&编程论坛(http://www.52exe.cn)感谢您的支持!
回复

使用道具 举报

发布主题 上个主题 下个主题 快速回复 返回列表 官方QQ群
在线客服
客 服 中 心
群 机 器 人
网站二维码
收 起 客 服

QQ|Archiver|手机版|小黑屋|Anycodes ( ICP14002806Anycodes在线编程

GMT+8, 2018-11-15 04:47 , Processed in 2.120679 second(s), 71 queries .

Powered by Anycodes

© 2001-2013 吉林市群龙科技有限公司 Inc.

快速回复 返回顶部 返回列表