• Tenka1 Programmer Contest 2019 D


    Three Colors

    思路:dp

    设sum为所有边的总和

    不能组成三角形的情况:某条边长度>=ceil(sum/2),可以用dp求出这种情况的方案数,然后用总方案数减去就可以求出答案。

    注意当某两条边都为sum/2的时候,dp会多算一次,要减去多算的方案数,多算的方案数也可以用dp求

    代码:

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    using namespace std;
    #define y1 y11
    #define fi first
    #define se second
    #define pi acos(-1.0)
    #define LL long long
    #define ls rt<<1, l, m
    #define rs rt<<1|1, m+1, r
    //#define mp make_pair
    #define pb push_back
    #define ULL unsigned LL
    #define pll pair<LL, LL>
    #define pli pair<LL, int>
    #define pii pair<int, int>
    #define piii pair<int, pii>
    #define pdi pair<double, int>
    #define pdd pair<double, double>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    //head
    
    const int N = 305, M = 9e4 + 10;
    const int MOD = 998244353;
    int a[N], dp[N][M], pp[M], n, s = 0;
    LL q_pow(LL n, LL k) {
        LL res = 1;
        while(k) {
            if(k&1) res = (res * n) % MOD;
            n = (n * n) % MOD;
            k >>= 1;
        }
        return res;
    }
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), s += a[i];
        dp[0][0] = 1;
        for (int i = 1; i <= n; ++i) {
            for (int j = 0; j < M; ++j) {
                dp[i][j] = (2*dp[i-1][j]) % MOD;
            }
            for (int j = a[i]; j < M; ++j) {
                dp[i][j] = (dp[i][j] + dp[i-1][j-a[i]]) % MOD;
            }
        }
        pp[0] = 1;
        for (int i = 1; i <= n; ++i) {
            for (int j = M-1; j >= a[i]; --j) pp[j] = (pp[j] + pp[j-a[i]]) % MOD;
        }
        if(s%2 == 0)dp[n][s/2] = (dp[n][s/2]-pp[s/2]) % MOD;
        LL ans = q_pow(3, n);
        int up = (s+1)/2;
        for (int i = up; i < M; ++i) ans = (ans - dp[n][i]*3LL%MOD) % MOD;
        printf("%lld
    ", (ans + MOD) % MOD);
        return 0;
    }
  • 相关阅读:
    Spring AOP前置通知实例说明AOP相关概念
    什么是面向切面编程AOP
    关于IOC容器的一些个人理解
    在.Net Core WebAPI下给Swagger增加导出离线文档功能
    .Net Core ORM选择之路,哪个才适合你
    真香.小程序云开发(时光邮局小程序)
    Cordova的安装与配置
    JS三座大山再学习(三、异步和单线程)
    JS三座大山再学习(二、作用域和闭包)
    JS三座大山再学习(一、原型和原型链)
  • 原文地址:https://www.cnblogs.com/widsom/p/10805335.html
Copyright © 2020-2023  润新知