경로 합계 CodeForces-1467D

경로 합계 CodeForces-1467D
Tagscombinatorics dp math * 2200

표제:

좋은 경로를 정의합니다. 어떤 지점에서 시작한 후 정확히 k 개의 움직임이 지나가는 경우에만이 경로의 가중치를 전달 된 지점의 가중치 합계 (반복)로 정의하고 q 번 수정하고 매번 ak를 변경합니다. x에 모든 '좋은'경로의 가중치 합계를 요청합니다.
예를 들면 다음과 같습니다.

5 1 5
3 5 1 4 2
1 9
2 4
3 6
4 6
5 2

첫 번째 자리를 9로 바꾸면 9 5 1 4 2가되고 해당 답은 62입니다.
여기에 사진 설명 삽입

대답:

dp 동적 프로그래밍
주제에 따라 각 그리드의 기여도를 계산해야합니다 .dp [i] [j]는 j 단계를 수행 한 후 점 i에서 총 경로 수를 나타냅니다. 점
i는 i-1 또는 i +에서 올 수 있습니다 . 1
에서 상태 전이 :
dp [i] [k] = dp [i-1] [k-1] + dp [i + 1] [k-1]
dp [i] [k]는 i 포인트가 어떤 포인트에 도달하기 위해 k 단계를 거쳐야하는 총 경로 수 (반대로
생각하는 것과 동일) 그렇다면 각 포인트의 기여도를 어떻게 고려할까요?
현재 지점 i가 m 걸음을 걸었다면 계획 수는 dp [i] [m]입니다. 총 k 걸음이 있기 때문에 가야 할 km 단계가 있으므로 계획 수는 dp [i] [ mk],이 포인트의 기여도는 ∑ m = 0 m = k dp [i] [m] * dp [i] [mk]
각 수정에 대해 i 번째 포인트의 값을 수정하고 먼저 원래 기여도를 뺍니다. i 번째 포인트의 새로운 기여도를 추가하십시오

암호:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){
    
    
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const int maxn=5e3+9;
const int mod=1e9+7;
ll a[maxn],c[maxn];
ll dp[maxn][maxn];
int main()
{
    
    
	int n,k,p;
	cin>>n>>k>>p;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n;i++)dp[i][0]=1;
	
	for(int i=1;i<=k;i++)//步数 
	{
    
    
		for(int j=1;j<=n;j++)//当前格子 
		{
    
    
			dp[j][i]=(dp[j-1][i-1]+dp[j+1][i-1])%mod;
		}
	}
	ll sum=0;
	for(int i=1;i<=n;i++)//当前格子 
	{
    
    
		for(int j=0;j<=k;j++)
		{
    
    
			c[i]=(c[i]+(dp[i][j]*dp[i][k-j])%mod)%mod;
		}
	}
	for(int i=1;i<=n;i++)sum=(sum+(a[i]*c[i])%mod)%mod;
	for(int i=1;i<=p;i++)
	{
    
    
		ll pos,x;
		cin>>pos>>x;
		sum=((sum-(a[pos]*c[pos])%mod)%mod+mod)%mod;
		a[pos]=x;
		sum=(sum+(a[pos]*c[pos])%mod)%mod;
		printf("%lld\n",sum);
	}
	return 0;
}
/*
Input
5 1 5
3 5 1 4 2
1 9
2 4
3 6
4 6
5 2
Output
62
58
78
86
86
*/

추천

출처blog.csdn.net/qq_35975367/article/details/114108448