1421. 數數(count)

1421. 數數(count)

題目描述

ftiasch 開發了一個奇怪的遊戲,這個遊戲的是這樣的:一個長方形,被分成N 行M 列的格子,第i 行第j 列的格子記爲(i, j),就是說,左上角的格子是(1,1),右下角的格子是(N,M)。開始的時候,nm 在(1,1),他需要走到(N,M)。每一步,nm 可以走到正右方或者正下方的一個格子。具體地說,如果nm 現在在(x, y),那麼他可以走到(x,y + 1) 或(x + 1,y)。當然,nm 不能走出離開這個長方形。
每個格子有積分,用一個1—10 的整數表示。經過這個格子,就會獲取這個格子的積分(起點和終點的積分也計算)。通過的方法是:到達(N,M) 的時候,積分恰好爲P。
現在給出這個長方形每個格子的積分,你需要幫助nm,求出從起點走到終點,積分爲P的線路有多少條。

輸入

第1 行,3 個整數N, M, P。接下來N 行,每行M 個整數Aij,表示格子(i, j) 的積分。

輸出

1 行,1 個整數,表示積分爲P 線路的數量。因爲數值太大,你只需要輸出結果除以(10^9 +7) 的餘數。

樣例輸入

3 3 9
2 2 1
2 2 2
1 2 2

樣例輸出

2

數據範圍限制

對於50% 的數據,1<= N,M<=10。
對於100% 的數據,1<=N,M<=100,0 <= Aij<=10。

50分(dfs)
超時!

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e2+10;
const int Mod=1e9+7;
int n,m,p,a[N][N],ans;
void input()
{
	scanf("%d%d%d",&n,&m,&p);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++) 
		scanf("%d",&a[i][j]);
}
bool check(int x,int y)
{
	if(x>=1&&x<=n&&y>=1&&y<=m) return 1;
	return 0;
}
void dfs(int x,int y,int s)
{
	if(x==n&&y==m&&s==p) 
	{
		ans=(ans+1)%Mod;	
		return;
	} 
	if(check(x+1,y)) dfs(x+1,y,s+a[x+1][y]);
	if(check(x,y+1)) dfs(x,y+1,s+a[x][y+1]);
}
int main()
{
	fre(count);
	input();
	dfs(1,1,a[1][1]);
	printf("%d",ans);
	return 0;
}

100分(dp)
這道題的狀態轉移方程是很簡單的(一道例題)。
只是f[i][j][k]我以爲最壞的情況k需要開到100000,所以保守地用了dfs。

按題意,對於nxn的矩陣,需2n-2步。因n最大100,所以k最大爲(2x100-2)x10≈2000。故k只需要開到2000。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e2+3;
const int M=2e3;
const int Mod=1e9+7;
int n,m,p,f[N][N][M],a[N][N];
void input()
{
	scanf("%d%d%d",&n,&m,&p);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++) 
		scanf("%d",&a[i][j]);
}
int main()
{
	fre(count);
	input();
	f[1][1][a[1][1]]=1;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	for(int k=a[i][j];k<=p;k++)
		{
			if(i==1&&j==1) continue;
			f[i][j][k]=(f[i-1][j][k-a[i][j]]+f[i][j-1][k-a[i][j]])%Mod;	
		}
	printf("%d",f[n][m][p]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章