2018 (csu 2164) (dfs打表+找規律)
阿新 • • 發佈:2019-01-26
Description
Bobo 想統計滿足下面條件的矩陣 A 的數量。
- 矩陣 A 有 n 行 m 列,每個元素都是正整數。第 i 行第 j 列的元素用 Ai, j 表示。
- A1, 1 = 2018.
- 對於所有 2 ≤ i ≤ n, 1 ≤ j ≤ m,Ai, j 是 Ai − 1, j 的約數。
- 對於所有 1 ≤ i ≤ n, 2 ≤ j ≤ m,Ai, j 是 Ai, j − 1 的約數。
因為滿足條件的矩陣 A 數量很多,Bobo 只想統計滿足條件的矩陣數量除以 (109 + 7) 的餘數。
- 1 ≤ n, m ≤ 2000
- 資料組數不超過 105.
Input
輸入檔案包含多組資料,請處理到檔案結束。
每組資料包含 2 個整數 n 和 m.
Output
對於每組資料輸出 1 個整數表示所求的數量除以 (109 + 7) 的餘數。
Sample Input
1 1 1 2 2 2 2 3 2000 2000
Sample Output
1 4 25 81 570806941
Hint
對於第二組樣例(n = 1, m = 2),滿足條件的矩陣 A 有 (2018, 2018),(2018, 1009),(2018, 2),(2018, 1) 共 4 種。
Source
2018湖南省第14屆大學生計算機程式設計競賽
老師佈置的任務,深夜補題,寫了個dfs打表,跑程式的時候筆記本卡茲卡茲,在草稿紙上畫畫,找找規律,然後A了....
/*#include<bits/stdc++.h> using namespace std; int n,m,a[100][100]; int d[4]={1,2,1009,2018},ans; void dfs(int x,int y) { if(x==n+1) { for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) printf("%d ",a[i][j]); printf("\n"); } ans++; } else { if(x==1) { for(int i=0;i<4;i++) { if(a[x][y-1]%d[i]==0&&!a[x][y]) { a[x][y]=d[i]; if(y==m) dfs(x+1,1); else dfs(x,y+1); a[x][y]=0; } } } else if(y==1) { for(int i=0;i<4;i++) { if(a[x-1][y]%d[i]==0&&!a[x][y]) { a[x][y]=d[i]; if(y==m) dfs(x+1,1); else dfs(x,y+1); a[x][y]=0; } } } else if(x<=n&&y<=m) { for(int i=0;i<4;i++) { if(a[x][y-1]%d[i]==0&&a[x-1][y]%d[i]==0&&!a[x][y]) { a[x][y]=d[i]; if(y==m) dfs(x+1,1); else dfs(x,y+1); a[x][y]=0; } } } } } int main() { while(scanf("%d%d",&n,&m)==2) { memset(a,0,sizeof(a)); ans=0; a[1][1]=2018; dfs(1,2); printf("%d\n",ans); } } */ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod=1e9+7; ll a[2002][2002],n,m; void pre() { for(ll i=1; i<=2000; i++) a[i][1]=i,a[i][0]=0; for(ll i=1; i<=2000; i++) a[1][i]=i; for(ll i=2; i<=2000; i++) { for(ll j=2; j<=2000; j++) { a[i][j]=a[i][j-1]+(a[i-1][j]-a[i-1][j-1])+(a[i][j-1]-a[i][j-2]); a[i][j]+=mod; a[i][j]%=mod; } } } int main() { pre(); while(scanf("%lld%lld",&n,&m)==2) { printf("%lld\n",(a[n][m]%mod)*(a[n][m]%mod)%mod); } }