Wikioi_1010 過河卒

http://www.wikioi.com/problem/1010/    


分析: 

        最先想到的是回溯,在Wikioi_1010 是680ms過的,但是在另外一個shuoj上就是TLE 然後就想起DP(2ms過)了;

        dp[i] [j] 存的是到達 (i,j)位置的方法數,初始化爲1,對於馬控制點應該是走不到的,所以設爲0;

        至於狀態轉移,由於卒只能向下和向右走,所以一般的: dp [ i ] [ j ] =  dp[ i-1] [ j ] + dp [ i ] [ j-1 ] ;

         注意i=0 和 j=0 的情況:

                  i=0 : dp[ i ][ j ] = dp[ i ] [ j-1 ];

                  j=0 : dp[ i ][ j ] = dp[ i-1 ] [ j ];


代碼:

       

#include <stdio.h>

int ans;
int n,m,cx,cy;

int abs(int e)
{
	return e > 0 ? e:-e;
}

bool judge(int x,int y)
{
	if(x==cx && y==cy) return 0;
	if(abs(x-cx)==1 && abs(y-cy)==2 || abs(x-cx)==2 && abs(y-cy)==1)
       return 0;
	return 1;
}

void dfs(int x,int y)
{
	if(x==n && y==m){
        ans++;
        return;
	}
	if(x>n || y>m)    return;
	if(judge(x,y)==0) return;
    dfs(x+1,y);
    dfs(x,y+1);
    return;
	//return dfs(a+1,b)+dfs(a,b+1);
}

int main()
{
	while(scanf("%d%d%d%d",&n,&m,&cx,&cy)!=EOF)
	{
		if(judge(n,m)==0)
			ans=0;
		else
			dfs(0,0);
		printf("%d\n",ans);
	}
}


#include <iostream>
#include <stdio.h>
using namespace std;
#define MAXN 24
 
int n,m,cx,cy;
long long dp[MAXN][MAXN];
 
void mark(int x,int y)
{
    dp[x][y] = 0;
    dp[x+2][y+1] = 0;
    dp[x+1][y+2] = 0;
    if(x>=1)dp[x-1][y+2] = 0;
    if(x>=2)dp[x-2][y+1] = 0;
    if(x>=2&&y>=1)dp[x-2][y-1] = 0;
    if(x>=1&&y>=2)dp[x-1][y-2] = 0;
    if(y>=2)dp[x+1][y-2] = 0;
    if(y>=1)dp[x+2][y-1] = 0;
}
void init()
{
    scanf("%d%d%d%d",&n,&m,&cx,&cy);
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            dp[i][j]=1;
    mark(cx,cy);
}
 
int main()
{
    init();
    for(int i=0; i<=n; i++){
        for(int j=0; j<=m; j++){
            if((!dp[i][j]))    continue;
            if(i==0 && j==0)   continue;
            else if(i==0)    dp[i][j] = dp[i][j-1];
            else if(j==0)    dp[i][j] = dp[i-1][j];
            else             dp[i][j] = dp[i-1][j] + dp[i][j-1];
        }
    }
    printf("%lld\n",dp[n][m]);
}
 


       

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章