hdu 1208 Pascal's Travels (子状态继承dp)

Pascal‘s Travels

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 1774    Accepted Submission(s): 781

Problem Description

An n x n game board is populated with integers, one nonnegative integer per square. The goal is to travel along any legitimate path from the upper left corner to the lower right corner of the board. The integer in any one square dictates how large a step away
from that location must be. If the step size would advance travel off the game board, then a step in that particular direction is forbidden. All steps must be either to the right or toward the bottom. Note that a 0 is a dead end which prevents any further
progress.

Consider the 4 x 4 board shown in Figure 1, where the solid circle identifies the start position and the dashed circle identifies the target. Figure 2 shows the three paths from the start to the target, with the irrelevant numbers in each removed.

Figure 1

Figure 2

Input

The input contains data for one to thirty boards, followed by a final line containing only the integer -1. The data for a board starts with a line containing a single positive integer n, 4 <= n <= 34, which is the number of rows in this board. This is followed
by n rows of data. Each row contains n single digits, 0-9, with no spaces between them.

Output

The output consists of one line for each board, containing a single integer, which is the number of paths from the upper left corner to the lower right corner. There will be fewer than 2^63 paths for any board.

Sample Input

4
2331
1213
1231
3110
4
3332
1213
1232
2120
5
11101
01111
11111
11101
11101
-1

Sample Output

3
0
7

简单dp,从起点开始每次走到一个格子,记下到达该点的原路线数目加上这次的路线数目,重复执行。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
using namespace std;
#define N 100
#define ll __int64
const int inf=0x7fffffff;
ll a[N][N];
ll dp[N][N];
char s[N][N];
int main()
{
    int i,j,n,u,v,t;
    while(scanf("%d",&n),n!=-1)
    {
        for(i=0;i<n;i++)
            scanf("%s",s[i]);
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                a[i][j]=s[i][j]-'0';
                dp[i][j]=0;
            }
        }
        dp[0][0]=1;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                if(i==n-1&&j==n-1)      //到达终点,防止累加错误
                    continue;
                if(!dp[i][j]||!a[i][j])  //此路不通
                    continue;
                t=a[i][j];          //每一步都只能直走,中途不能拐弯
                u=i+t;
                v=j;
                if(u<n&&v<n)
                {
                    dp[u][v]+=dp[i][j];
                }
                u=i;
                v=j+t;
                if(u<n&&v<n)
                {
                    dp[u][v]+=dp[i][j];
                }
            }
        }
        printf("%I64d\n",dp[n-1][n-1]);
    }
    return 0;
}

hdu 1208 Pascal's Travels (子状态继承dp)

时间: 2024-07-29 00:43:42

hdu 1208 Pascal's Travels (子状态继承dp)的相关文章

HDU 1208 Pascal&#39;s Travels( 记忆化搜索)

题目大意:每一小格代表能向右或者向下走几步,问从左上走到右下总共有多少种走法. dp[i][j]存放该格子有多少总走法. #include <iostream> #include <cstring> using namespace std; int n; char a[40][40]; int s[40][40]; __int64 dp[40][40]; int X[]={1, 0}; int Y[]={0, 1}; __int64 dfs(int x, int y) { if(d

HDU 3001 Travelling (三进制状态压缩 DP)

题意:有 n 个city,可以选择任一城市作为起点,每个城市不能访问超过2次, 城市之间有权值,问访问全部n个城市需要的最小权值. 思路:因为每个城市可以访问最多两次,所以用三进制表示访问的状态. 详细见代码注释!!!! #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #inclu

[hdu4628 Pieces]二进制子状态,DP

题意:给一个长度为16的字符串,每次从里面删掉一个回文序列,求最少需要几次才能删掉所有字符 思路:二进制表示每个字符的状态,那么从1个状态到另一个状态有两种转移方式,一是枚举所有合法的回文子序列,判断是否是当前状态的子状态,再转移,二是枚举当前状态的所有子状态来转移.前者最坏复杂度O(2^16*2^16) = O(几十亿),而后者最坏只有(i:1->16)Σ2iC(16,i) = O(几千万). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

hdu 5067 Harry And Dig Machine (状态压缩dp)

题目链接 bc上的一道题,刚开始想用这个方法做的,因为刚刚做了一个类似的题,但是想到这只是bc的第二题, 以为用bfs水一下就过去了,结果MLE了,因为bfs的队列里的状态太多了,耗内存太厉害. 题意: 从某一点出发,遍历网格上的一些点,每个点至少访问一次需要的最小时间是多少. 官方题解: 由于Harry的dig machine是无限大的,而装载石头和卸载石头是不费时间的,所以问题可以转化成:从某一点出发,遍历网格上的一些点,每个点至少访问一次需要的最小时间是多少.这就是经典的旅行商问题,考虑到

HDU 5418 Victor and World (状态压缩dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 题目大意:有n个结点m条边(有边权)组成的一张连通图(n <16, m<100000).求从第一个点出发,经过每个点至少一次后回到原点的最小路径边权和. 分析:发现我还真是菜. n<16,很明显的状态压缩标记,先将所有点的编号减去1,使其从0开始编号.dp[i][j]表示从0号点出发,当前状态为i (二进制位为1表示对应点已走过,否则没走过), 当前位置为 j,  回到原点的最小代价,

hdu 1565 方格取数(1) (状态压缩+dp)

方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5589    Accepted Submission(s): 2123 Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出

HDU 4640 Island and study-sister(状态压缩DP+路径压缩)经典 旅行商问题

Island and study-sister Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 790    Accepted Submission(s): 273 Problem Description Members of ACM/ICPC teams of Fuzhou University always stay in th

HDU 1208 跳格子题(很经典,可以有很多变形)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1208 Pascal's Travels Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2795    Accepted Submission(s): 1298 Problem Description An n x n game board

HDU 4628 Pieces(状态压缩DP)

题目链接:传送门 题意: 给定一个长度小于16的字符串然后每次可以去掉它的一个回文子序列,问最少删除多少次可以使这个字符串为空. 分析: 首先预处理出这个字符串的所有回文子序列,然后将其压缩成二进制x,然后dp[x]表示这个序列删除所需要的最小的步数,然后dp[x] = min(dp[x],dp[sub])sub表示x的所有子序列. 代码如下: #include <iostream> #include <string> #include <cstring> #inclu