Codeforces Round # 581 (Div. 2) -E. Natasha, Sasha and the Prefix Sums- dynamic programming + combinatorics

Codeforces Round # 581 (Div. 2) -E. Natasha, Sasha and the Prefix Sums- dynamic programming + combinatorics


【Problem Description】

You \ (n-\) a \ (1 \) , \ (m \) a \ (- 1 \) , they are arranged in any \ (\ frac {(n + m)!} {N \ cdot m! !} \) in the arrangement, each arrangement has a maximum prefix and (possibly \ (0 \) ), all seeking the maximum sum of prefixes, and how much.

【Solution】

Defined \ (dp [i] [j ] \) expressed \ (I \) a \ (1 \) , \ (J \) th \ - (1 \) in all of the maximum prefix and is arranged and when \ (DP [I] [J] \) . The state transition equation is: \ (DP [I] [J] DP = [. 1-I] [J] + C_ {I + J-J. 1} ^ {} + DP [I] [J-. 1] -C_ I-J. 1 + {}} ^ {I + K [I] [J] \) . Wherein \ (k [i] [j ] \) expressed \ (I \) a \ (1 \) , \ (J \) a \ (- 1 \) when the maximum prefix and is \ (0 \) arranged number.

Wherein \ (dp [i-1] [j] + C_ {i + j-1} ^ j \) represents a newly added digit \ (1 \) , the most distal end into which all permutations of all arrayed maximum prefix and have increased \ (1 \) , and a total of \ (C_ {i + j- 1} ^ j \) permutations, so increased based on the original \ (C_ {i + j- 1} J ^ \) .

\ (dp [i] [j -1] -C_ {i + j-1} ^ i + k [i] [j] \) represents a newly added digital \ (- 1 \) , the arrangement of all supra and reducing the maximum prefix \ (1 \) , in addition to the maximum and the prefix \ (0 \) arrangement.

Why \ (i-1 \) a \ (1 \) , \ (J \) a \ (- 1 \) is the number of all permutations \ (C_ {i + j- 1} ^ j \) then ? The arrangement is because multiple sets of equations \ (\ frac {((i -1) + j)!} {(I-1)! \ Cdot j!} \) Obtained.

Maximum prefix and \ (k [i] [j ] \) how find it? \ (K [I] [J] = K [. 1-I] [J] K + [I] [J-. 1] \) . Represents guaranteed \ (i \ le j \) in the case where, add a new digital \ (1 \) , the number of which is arranged into the end of a newly added plus \ (- 1 \) , which is placed at the end the number of permutations.

The last question, why \ (DP \) array \ (1, -1 \) to be placed in the front end, \ (K \) array \ (1, -1 \) to be placed at the end, and why can not simultaneously on the front and rear as well as any other location? \ (DP \) array is placed in the front end and the maximum because the maximum prefix requirements, such as the extra \ (1 \) on the rear end so that the maximum possible prefix and a certain maximum, \ (K \) array on because the rear end of the prefix and the maximum requirements for the \ (0 \) , such as the extra \ (1 \) on the front end, the maximum and minimum is equal to the prefix \ (1 \) .

It can not be placed in other positions as long as a discharge location contains all possible permutations, if the same calculation is repeated elsewhere in the number of permutations possible. For example, \ (I \) a \ (1 \) , \ (J \) a \ (- 1 \) , understood as the number of their arrangement all \ (C_ {I + J ^ J} \) , if \ (i-1 \) a \ (1 \) , \ (J \) a \ (- 1 \) , then the total number of the arrangement \ (C_ {I + J-J. 1} ^ \) , if there \ (I \) a \ (1 \) , \ (J \) a \ (- 1 \) , then the total number of the arrangement is \ (C_ {i + j- 1} ^ i = C_ {i + ^ {}. 1-J-J. 1} \) . The relationship between them is:
\ [C_ {I + J} ^ {C_ {J} = I + J-J. 1} ^ {} + {I + J-C_. 1. 1-J} ^ {} \]
by the Pascal formula indicates the establishment of a certain type. It is possible to know in which position determines the meaning of the array, determined by the relationship can only put \ (1 \) position.


【Code】

/*
 * @Author: Simon 
 * @Date: 2019-08-28 19:32:35 
 * @Last Modified by: Simon
 * @Last Modified time: 2019-08-28 20:26:23
 */
#include<bits/stdc++.h>
using namespace std;
typedef int Int;
#define int long long
#define INF 0x3f3f3f3f
#define maxn 2005
const int mod=998244853;
int dp[maxn][maxn]/*i个1,j个-1的所有排列的最大前缀和之和为dp[i][j]*/,k[maxn][maxn]/*i个1,j个-1的所有排列的最大前缀和为0的个数*/;
int bit[maxn<<1],C[maxn<<1][maxn<<1]/*组合数组*/;
Int main(){
#ifndef ONLINE_JUDGE
    //freopen("input.in","r",stdin);
    //freopen("output.out","w",stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,m;cin>>n>>m;
    bit[0]=1;C[0][0]=1;
    for(int i=1;i<=n+m;i++) bit[i]=bit[i-1]*i%mod,C[i][0]=1;
    for(int i=1;i<=m;i++) k[0][i]=1;
    for(int i=1;i<=n+m;i++){ //预处理
        for(int j=1;j<=n+m;j++){
            if(j>=i&&i<=n&&j<=m) k[i][j]=(k[i-1][j]+k[i][j-1])%mod;
            if(i>=j) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
        }
    }
    for(int i=1;i<=n;i++) dp[i][0]=i;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            dp[i][j]=((dp[i-1][j]+C[i+j-1][j]+dp[i][j-1]-C[i+j-1][i]+k[i][j-1])%mod+mod)%mod;
        }
    }
    cout<<(dp[n][m]+mod)%mod<<endl;
#ifndef ONLINE_JUDGE
    cout<<endl;system("pause");
#endif
    return 0;
}

Guess you like

Origin www.cnblogs.com/--Simon/p/11429113.html