最新文章

这里会显示最新的几篇文章摘要。

能源晶体(DP)

问题 D: 能源晶体

题目描述

在一个遥远的未来,人类已经进入了星际时代,各大星系之间依靠一种稀有的能源晶体来维持星际飞船的运行。这种能源晶体极其珍贵且具有强大的能量,能够为整个星际舰队提供动力。

Luke 是银河联邦的一名高级能源工程师,他的任务是管理和调配这些稀有的能源晶体。联邦给他分配了 n 个高能晶体模块,这些模块需要放入 k 个能量储存舱中。每个储存舱必须至少分配一个高能晶体模块,以保证没有浪费。

由于晶体能量的特殊性质,不同的分配方式会导致能量场的不同排列。这些排列在维持星际平衡中起着至关重要的作用。因此,Luke 需要找出所有可能的晶体分配方式,并计算它们的总数。

然而,星际能源系统的复杂性极高,可能的分配方案数非常庞大,因此计算结果需要对 998244353 取模,确保数据在银河级计算机中能够正常处理。

作为银河联邦的重要工程师,Luke 需要你的帮助来完成这项艰巨的任务!你能帮助他计算出所有可能的分配方式并确保星际平衡吗?

输入

第一行输入两个正整数 n, k。

输出

输出一行一个整数表示计算结果对 998244353 取模的结果。

样例输入

【样例1】7 3
【样例2】200 6

样例输出

【样例1】4
【样例2】4132096

提示

样例 1 解释:共有 (1, 1, 5), (1, 2, 4), (1, 3, 3), (2, 2, 3)四种情况

数据范围

分析

题意把n个物品分成k份,每份至少一个,可以转化一下,把n-k(提前每一份放置一份)份物品分成k份,每份可以为0,这样转换后使用动态规划,
dp[i][j] 为把i份物品分成j份的情况数,那么有两种情况,第一种情况为k份每一份都至少有一个dp[i-j][j],当然要i >= j
第二种情况是,存在某一份为0的情况,dp[i][j-1],所有状态转移就为

    if(i >= j) dp[i][j] = dp[i-j][j] + dp[i][j-1]
    else dp[i][j] = dp[i][j-1]

注意边界为dp[0][0] = 1

const int N = 998244353;
int dp[5005][5005];

signed main(){
    cin >> n >> k;
    n -= k;
    
    for(int i = 1;i <= n; i++)
        for(int j = 1;j <= k;++j)
        {
            if(i >= j) dp[i][j] = dp[i-j][j] % N + dp[i][j-1] % N;
            else dp[i][j] = dp[i][j-1];
        }
    cout << dp[n][k] % N;
}
posted @ 2025-03-15 16:05  bakul  阅读(107)  评论(0)    收藏  举报