2022十三届蓝桥杯国赛题解

张春  金牌会员 | 2022-6-25 14:10:33 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 780|帖子 780|积分 2340

  1.                                                 **特此声明,本文仅为参考文档,标准答案请参考官方文档**
复制代码
试题A

该题是一道背包dp题,我的思路是定义三维dp,第一维表示第i个数,第二维表示前i个数的总和为j,第三维表示前i个数,总和为j,第i个数为z的方案数。
首先观察这个题的性质,要求互不相同,首先我们需要找一个严格递增的序列,并且序列的总和为2022
刚开始我也是想到的一个O(n3)的dp 状态转移,但是我们发现其中一维可以通过优化去掉变成O(n2)dp,然后成功算出答案。
需要注意的是需要开                              l                      o                      n                      g                      l                      o                      n                      g                          long long               longlong因为答案太大爆int
然后推出方程式:
                                    i                         f                         (                         k                         >                         z                         )                         c                         o                         n                         t                         i                         n                         u                         e                         ;                         /                         /                         表                         明                         当                         前                         总                         和                         装                         不                         下                         当                         前                         项                              if(k > z) continue ; //表明当前总和装不下当前项                  if(k>z)continue;//表明当前总和装不下当前项
                                    i                         f                         (                         k                         a                         n                         d                         z                         >                         =                         k                         )                         /                         /                         我                         们                         可                         以                         给                         当                         前                         枚                         举                         项                         加                         一                         构                         造                         新                         的                         方                         案                              if(k and z >= k) //我们可以给当前枚举项加一构造新的方案                  if(kandz>=k)//我们可以给当前枚举项加一构造新的方案
                                    f                         [                         i                         ]                         [                         z                         ]                         [                         k                         ]                         +                         =                         f                         [                         i                         −                         1                         ]                         [                         z                         −                         k                         ]                         [                         k                         −                         1                         ]                         ;                              f[z][k] += f[i - 1][z - k][k - 1] ;                  f[z][k]+=f[i−1][z−k][k−1];
                                    i                         f                         (                         z                         a                         n                         d                         k                         )                         /                         /                         表                         明                         我                         们                         选                         的                         当                         前                         项                         必                         须                         比                         上                         一                         项                         严                         格                         大                              if(z and k)//表明我们选的当前项必须比上一项严格大                  if(zandk)//表明我们选的当前项必须比上一项严格大
                                    f                         [                         i                         ]                         [                         z                         ]                         [                         k                         ]                         +                         =                         f                         [                         i                         ]                         [                         z                         −                         1                         ]                         [                         k                         −                         1                         ]                         ;                              f[z][k] += f[z - 1][k - 1] ;                  f[z][k]+=f[z−1][k−1];
代码如下
[code]#include #include #include using namespace std ;long long ans ;long long f[20][3000][3000] ; // 个数 总和 上一项int main(void){        f[0][0][0] = 1 ;        for(int i = 1 ; i

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张春

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表