• 【51nod】2589 快速讨伐


    51nod 2589 快速讨伐

    又是一道倒着推改变世界的题。。。

    从后往前考虑,设(dp[i][j])表示还有(i)个1和(j)(2)没有填,那么填一个1的话直接转移过来

    (dp[i][j] ightarrow dp[i - 1][j])

    如果填一个(2)要把(A[j])的那些敌人都扔在这个2的后面

    方案是

    (inom{N - i + N - j + sum[N] - sum[j - 1]}{A[j]} A[j]! dp[i][j] ightarrow dp[i][j - 1])

    然后把(i < j)的状态都标成0就好了

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define ba 47
    #define MAXN 2005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    const int MOD = 998244353,MAXV = 4000000;
    int N;
    int A[MAXN],s[MAXN];
    int fac[MAXV + 5],invfac[MAXV + 5];
    int dp[MAXN][MAXN];
    int inc(int a,int b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }
    int mul(int a,int b) {
        return 1LL * a * b % MOD;
    }
    void update(int &x,int y) {
        x = inc(x,y);
    }
    int C(int n,int m) {
        if(n < m) return 0;
        else return mul(fac[n],mul(invfac[m],invfac[n - m]));
    }
    int fpow(int x,int c) {
        int res = 1,t = x;
        while(c) {
    	if(c & 1) res = mul(res,t);
    	t = mul(t,t);
    	c >>= 1;
        }
        return res;
    } 
    void Solve() {
        read(N);
        for(int i = 1 ; i <= N ; ++i) read(A[i]);
        s[0] = 1;
        for(int i = 1 ; i <= N ; ++i) s[i] = s[i - 1] + A[i];
        fac[0] = 1;
        for(int i = 1 ; i <= MAXV ; ++i) fac[i] = mul(fac[i - 1],i);
        invfac[MAXV] = fpow(fac[MAXV],MOD - 2);
        for(int i = MAXV - 1 ; i >= 0 ; --i) invfac[i] = mul(invfac[i + 1],i + 1);
        dp[N][N] = 1;
        for(int i = N ; i >= 0 ; --i) {
    	for(int j = N ; j >= 0 ; --j) {
    	    if(i < j) {dp[i][j] = 0;continue;}
    	    if(i && i - 1 >= j) {
    		update(dp[i - 1][j],dp[i][j]);
    	    }
    	    if(j) {
    		update(dp[i][j - 1],mul(mul(dp[i][j],fac[A[j]]),C(N - i + N - j + s[N] - s[j - 1],A[j])));
    	    }
    	}
        }
        out(dp[0][0]);enter;
    }
    int main(){
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
        return 0;
    }
    
  • 相关阅读:
    Jquery消息提示插件toastr使用详解
    spingboot jar 包启动遇到得坑
    freemarker使用shiro标签(spring boot)
    sping boot 集成shiro
    java 线程安全(初级)
    java GC jvm 内存分布 和新生代,老年代,永久代,(详细)
    java的新生代 老年代 永久代
    windows下rabbitmq(架构师必备神器)集群搭建
    友盟移动开发平台.NET版本SDK
    jstree无限级菜单ajax按需动态加载子节点
  • 原文地址:https://www.cnblogs.com/ivorysi/p/11050172.html
Copyright © 2020-2023  润新知