1. 程式人生 > >HDU 1208 跳格子題(很經典,可以有很多變形)

HDU 1208 跳格子題(很經典,可以有很多變形)

tar where no space osi bit cpp ogre 理解 accep

題目鏈接:

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 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 Hint Hint Brute force methods examining every path will likely exceed the allotted time limit. 64-bit integer values are available as "__int64" values using the Visual C/C++ or "long long" values using GNU C/C++ or "int64" values using Free Pascal compilers.

Source Mid-Central USA 2005 分析; 看到一句話: 所謂動態規劃,就是每一個階段你要做出一個決策,從最開始的決策到結束的決策的集合叫做一個策略,而各個階段決策的多樣性直接導致了策略的多樣性,而我們一般求得的不是最有策略結束最大最小花費策略,每一個階段的決策在這種有目的的作用下都與上一個階段的決策相關,我們用記錄這個階段的一個東西(通常是動態數組)來記錄這個狀態符合我們需要的策略的決策 唉,還是不能很好的理解dp思想 本題分析; 要 求左上角到右下角的方法數 每次只能往下或者往右跳,跳的格子數必須等於現在站的格子的權值(不能少跳,比如你站的格子中權值是3,那麽你在不超出邊界的條件下你一定要跳3個格子),這樣一來,有的格子可能跳不到,而有的格子可能有多種到達的方式 dp[i][j] 表示到達i,j的方法數目 註意: 1.初始化問題:dp初始化為0,dp[0][0]=1 2.狀態轉移方程: dp[i][j+a[i][j]]+=dp[i][j]; dp[i+a[i][j]][j]+=dp[i][j]; 不超邊界的前提下(j+a[i][j]<n i+a[i][j]<n) 3.long long 類型(註意題目中拿到2的63次方) 代碼如下:
#include<bits/stdc++.h>
using namespace std;
#define max_v 40
long long dp[max_v][max_v];//dp[i][j] 表示到達i行j列有多少種走法
long long a[max_v][max_v];
char s[max_v];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        if(n==-1)
            break;
        getchar();
        for(int i=0;i<n;i++)
        {
            scanf("%s",s);
            for(int j=0;j<strlen(s);j++)
            {
                a[i][j]=s[j]-‘0‘;
            }
        }
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(a[i][j]==0)//防止死循環
                    continue;
                if(j+a[i][j]<n)//向右邊跳
                {
                    dp[i][j+a[i][j]]+=dp[i][j];
                }
                if(i+a[i][j]<n)//向下跳
                {
                    dp[i+a[i][j]][j]+=dp[i][j];
                }
            }
        }
        printf("%lld\n",dp[n-1][n-1]);
    }
    return 0;
}

  

HDU 1208 跳格子題(很經典,可以有很多變形)