题解 P5239 【回忆京都】

· · 题解

Updated at 2019/3/2/21:56,重新发表

(实际上是发表后几小时,有一位大佬@dou_bao想出了递推式的推导方法(已获得他的授权))

看了诸位大佬的题解,蒟蒻一脸懵逼

难道我写出了本题最短代码???

毕竟是自己YY出的野递推式

下面是推导过程,看不懂可以自行跳过

为毛是这样的 ?

感谢@dou_bao大佬的解释。(已获得原作者授权)

我们需要三张表

1.帕斯卡三角形(即杨辉三角)(数组f

1
1 1 0 0 0 0 0 0
1 2 1 0 0 0 0 0
1 3 3 1 0 0 0 0
1 4 6 4 1 0 0 0
1 5 10 10 5 1 0 0
1 6 15 20 15 6 1 0
for(int i=1;i<=x;i++)
    for(int j=2;j<=y;j++)
        ans+=f[i][j];

2.帕斯卡三角形的前缀和(横着的)(不包括每行第一个数1)(数组g

1 1 1 1 1 1
2 3 3 3 3 3
3 6 7 7 7 7
4 10 14 15 15 15
5 15 25 30 31 31
6 21 41 56 62 63

3.帕斯卡三角形横着的前缀和的前缀和(竖着的)(数组ans

1 1 1 1 1 1
3 4 4 4 4 4
6 10 11 11 11 11
10 20 25 26 26 26
15 35 50 56 57 57
21 56 91 112 119 120

证毕。

于是......这就是我的只有15行的代码了(未压行):

#include<iostream>
using namespace std;
int ans[1005][1005],q,n,m;
int main() {
    for(int i=1;i<=1000;i++)
    for(int j=1;j<=1000;j++) {
        ans[i][j]=(ans[i-1][j-1]+ans[i-1][j]+i)%19260817;
    }
    cin>>q;
    while(q--) {
        cin>>n>>m;
        cout<<ans[m][n]<<endl;
    }
    return 0;
}