Luogu P4707は、(包含と除外、DPを拡大する最小 - 最大)この世界に戻ります

トピックリンク

https://www.luogu.org/problem/P4707

問題の解決策

最近不滅の質問エイスバースト......

まず、最小-最大の包含と除外確かに考えることができ、この問題は最小-最大容量は非難--Kthタイトルの拡張バージョンを使用することで
、この事が包含と除外最小-最大の性質のより深い理解を持っている必要があります。
まず、別の角度からの包含および除外の最小-最大の正当性を実証した:\(\ MAX(S)= \ sum_ F(IN {T \ S} | T |)\分(T)\)最初のために、(\ (X + 1)\)それについて計算された多数回\(\ sum_ {K \ 0} GE {X \ K} F(K +を選択してください。1)\) そこ\([X = 0] = \ sum_ {K \ 0} GE {X \ K}を選択F(K + 1)\)その結果、反転二項の後に\(F(k)=( - 1)^ {K-1} \) 自分の目標を達成します。
だから式を考える(\ [X = 0] \ ) に([X = K-1 \ ] \) まだどのように構造因子のアイデアを取るだろう、結果は:?です\(F [X- ] =( - 1)^ {} {XK-X 1つの\ K-選択1。。} \)

第一の問題は、シークに対応する\(K \)所望の大きなサブセット最小に変換することができる:\(\テキストkthmax} {Sで(S)= \ sum_ {T \}( - 1)^ {| T | -K} {| T | -1 Sで\} K-1を選択\分(T)= \ sum_ {T \} \ FRAC {M} {P_T}( - 1)^ {| T |} -K {| T | -1 \選択-K 1} \) \は(P_T = \ sum_ {iが
Tで\} P_I \) 、これは彼のDPを行うものであってもよい:う\(DP [I] [J ] [K] \)前進を表す\(Iは\)\(P \)の合計\(J \)メトリックの数、\(K \)は各受信プログラム反発係数を乗じそして、。
転送考察:最初の場合は\(私は\)の要素はに属していない(T \)を\明らかにプラス、([1-I] [J] [K] \ DP)\ ;彼らがある場合は、\(T \) その後、必要な組み合わせの数\({| T | -1選択-K \ 1} = {| T | -2選択-K + \ 1 {} |。T | -2選択K-2 \} \) 以前のために直接入力である(DP [-I 1] [P_I-J] [K]を\)\から、後者のために、\(K-1 \)これ以上を取るために、オーバー転送\(--1 \) 最終結果はマイナスである\((DP [I-1 ] [J-P_I] [K] -dp [I-1]〜[J-P_I] [ 1-K])\)
取り扱いが困難しかし、このDP境界問題。その後、我々はとき、負の直接置換可能な定義されたインデックスにある組み合わせの数を考えるために、実用上の問題からかもしれません\(DP [0] [0] [K] = - 1(K> 0)\) 。
ただし、この感覚は、厳密な境界設定方法ではありません)

時間複雑\(O(NM(NK))\)

コード

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<iostream>
#define llong long long
using namespace std;

inline int read()
{
    int x=0; bool f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
    for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
    if(f) return x;
    return -x;
}

const int N = 1000;
const int S = 1e4;
const int M = 11;
const int P = 998244353;
llong quickpow(llong x,llong y)
{
    llong cur = x,ret = 1ll;
    for(int i=0; y; i++)
    {
        if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur%P;}
        cur = cur*cur%P;
    }
    return ret;
}
llong mulinv(llong x) {return quickpow(x,P-2);}

llong a[N+3];
llong dp[S+3][M+2];
int n,m,s;

int main()
{
    scanf("%d%d%d",&n,&m,&s); m = n-m+1;
    for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
    for(int i=1; i<=m; i++) dp[0][i] = P-1;
    for(int i=1; i<=n; i++)
    {
        for(int j=s; j>=a[i]; j--)
        {
            for(int k=1; k<=m; k++)
            {
                dp[j][k] = (dp[j][k]+dp[j-a[i]][k-1]-dp[j-a[i]][k]+P)%P;
            }
        }
    }
    llong ans = 0ll;
    for(int i=1; i<=s; i++)
    {
        ans = (ans+dp[i][m]*s%P*mulinv(i))%P;
    }
    printf("%lld\n",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/suncongbo/p/11278273.html