1. 程式人生 > 其它 >CF #695 (Div. 2) D. Sum of Paths//dp

CF #695 (Div. 2) D. Sum of Paths//dp

題意

有個機器人在 [ 1 , n ] [1,n] [1,n]的直線方格上面走 k k k步,求所有路線下每個格子經過的次數。

思路

d p [ i ] [ j ] dp[i][j] dp[i][j]:走 i i i步到 j j j方格的路線數。
對於每一個方格,列舉他作為中轉點即可。

在這裡插入圖片描述

這dp。。。

/*   Author : Rshs   */
#include<bits/stdc++.h>
using namespace std;
#define FI         first
#define SE         second
#define LL         long long
#define LDB long double #define MP make_pair #define PII pair<int,int> #define SZ(a) (int)a.size() #define DB1(a) cerr<<(#a)<<'='<<a<<endl #define DB2(a,b) cerr<<(#a)<<'='<<a<<' '<<(#b)<<'='<<b<<endl
#define DB3(a,b,c) cerr<<(#a)<<'='<<a<<' '<<(#b)<<'='<<b<<' '<<(#c)<<'='<<c<<endl const LDB pai = acos(-1.0L); const LDB eps = 1e-10; const LL mod = 1e9+7; const int MXN = 5000+5; inline int Add(int x,int y){return (x+=y)>=mod?x-
mod:x;} inline int Sub(int x,int y){return (x-=y)<0?x+mod:x;} inline int Mul(int x,int y) {return 1LL*x*y%mod;} inline int Pow(int x,LL y){int res=1;while(y){if(y&1)res=1LL*res*x%mod;x=1LL*x*x%mod;y>>=1;}return res;} LL a[MXN]; LL dp[MXN][MXN]; LL sum[MXN]; int main(){ int n,k,q;cin>>n>>k>>q; for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); } for(int i=1;i<=n;i++) dp[0][i]=1; for(int i=1;i<=k;i++){ dp[i][1]=dp[i-1][2];dp[i][n]=dp[i-1][n-1]; for(int j=2;j<n;j++){ dp[i][j]=(dp[i-1][j-1]+dp[i-1][j+1])%mod; } } for(int i=1;i<=n;i++){ for(int j=0;j<=k;j++) sum[i]=(sum[i]+dp[j][i]*dp[k-j][i]%mod)%mod; } LL ans=0; for(int i=1;i<=n;i++) ans=(ans+sum[i]*a[i]%mod)%mod; while(q--){ LL i,x;scanf("%lld%lld",&i,&x); ans=((ans-sum[i]*a[i]%mod+sum[i]*x%mod)%mod+mod)%mod; cout<<ans<<'\n'; a[i]=x; } return 0; }