Stay Hungry,Stay Foolish!

E - Alphabet Tiles

E - Alphabet Tiles

https://atcoder.jp/contests/abc358/tasks/abc358_e

 

思路

dp[i][j] --- 前i项组成j长度字符串的 方案总数。

状态转移为:

dp[i-1][j] * combination[j+l][l]  ----> dp[i][j+l]

l == 0, 1, ..., ci

 

 

Code

https://atcoder.jp/contests/abc358/submissions/54674227

 

typedef long long ll;

ll k;
ll c[30];

const ll mode = 998244353;

ll combination[1005][1005];
ll dp[30][1005];


void calc_combination(){
    combination[0][0] = 1;

    for(int i=1; i<=1000; i++){
        /*
        if none of i items is chosen,
        only one case exists
        */
        combination[i][0] = 1;
        combination[i][i] = 1;

        for(int j=1; j<=i; j++){
            /*
            if j item is chosen, the combination is from preceding i-1 items to chose j-1 items
            if j item is not chosen, all j items are from preceding i-i items.
            */
            combination[i][j] = combination[i-1][j-1] % mode + combination[i-1][j] % mode;
            combination[i][j] %= mode;
        }
    }
}

int main()
{
    calc_combination();
    
//    cout << "----- after calc combination -------"<< endl;

    cin >> k;
    
    for(int i=1; i<=26; i++){
        cin >> c[i];
    }

    /*
    if target string length is zero,
    then the valid case number is one.
    */
    dp[0][0] = 1;

//    cout << "----- dp init -------"<< endl;

    /*
    caculating dp
    */
    for(int i=1; i<=26; i++){
        for(int j=0; j<=k; j++){
            for(int l=0; l<=c[i]; l++){
                /*
                after adding i-th options, total length overflow k
                so to break
                */
                if (j+l>k){
                    break;
                }
                
                /*
                otherwise,
                adding i-th item,
                the total case number can be calcuted based on the dp of the previous i-1 items.
                i.e. the previous i-1 items compromise j-l string length, l is the possible length to make string length less than k
                so for the left l chars,
                they can be filled by i-th item with the combination l of j.
                */
                dp[i][j+l] += (dp[i-1][j] * combination[j+l][l]) % mode;
                dp[i][j+l] %= mode;
            }
        }
    }

    ll ans = 0;

    for(int i=1; i<=k; i++){
        ans += dp[26][i];
        ans %= mode;
    }

    cout << ans << endl;

    return 0;
}

 

posted @ 2024-06-17 23:40  lightsong  阅读(2)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel