• 【LOJ6089】小 Y 的背包计数问题(背包+阈值)


    点此看题面

    大致题意: 有一个大小为(n)的背包和(n)种物品,其中第(i)种物品体积为(i)、数量为(i)。求把背包恰好装满的方案数。

    阈值

    法老讲课题,一道非常有技巧也非常有启发性的题目。

    这个问题直接去看就是一个多重背包,但实际上我们考虑,令(S=sqrt n),则体积大于(S)的物品肯定无法全部放入背包中,可以看作有无限个。

    也就是说,我们可以对体积小于等于(S)的物品做多重背包,对体积大于(S)的物品做完全背包。

    最后的合并答案实际上只要(O(n))扫一遍就可以了。

    多重背包

    众所周知,多重背包计数问题可以转化为完全背包。

    只要先跑一遍完全背包,然后倒序枚举(j),令(f_{i,j})减去不合法答案(f_{i,j-(i+1) imes i}),就可以了。

    由于只有(sqrt n)个物品体积小于等于(S),复杂度为(O(nsqrt n))

    完全背包

    考虑体积大于(S)的物品个数仍旧是(O(n))的,暴力完全背包复杂度依旧是(O(n^2))

    这里就涉及一个非常巧妙的优化。

    我们假设当前选了(i)个物品,体积总和为(j),接下来我们有两种操作方式:

    • 新增一个物品,体积为(S+1)
    • 给当前所有的物品体积加(1)

    不难发现,所有的方案都可以通过这两种操作方式唯一得到。

    也就是说,每次枚举(i,j),令(g_{i+1,j+S+1})(g_{i,j+i})分别加上(g_{i,j})

    由于最多只能选(S)个物品,复杂度为(O(nsqrt n))

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define SN 320
    #define X 23333333
    #define Inc(x,y) ((x+=(y))>=X&&(x-=X))
    using namespace std;
    int n,s;
    int f[SN+5][N+5];I void DP1()//体积小于等于S,多重背包
    {
    	RI i,j;for(f[0][0]=i=1;i<=s;++i)
    	{
    		for(j=0;j<=n;++j) f[i][j]=(f[i-1][j]+(j>=i?f[i][j-i]:0))%X;//完全背包
    		for(j=n;j>=(i+1)*i;--j) Inc(f[i][j],X-f[i][j-(i+1)*i]);//减去不合法答案
    	}
    }
    int g[SN+5][N+5],tot[N+5];I void DP2()//体积大于S,完全背包
    {
    	RI i,j;for(g[0][0]=1,i=0;i<=s;++i) for(j=0;j<=n;++j) Inc(tot[j],g[i][j]),//tot统计答案
    		j+s+1<=n&&Inc(g[i+1][j+s+1],g[i][j]),j+i<=n&&Inc(g[i][j+i],g[i][j]);//两种转移
    }
    int main()
    {
    	RI i,t=0;for(scanf("%d",&n),s=sqrt(n),DP1(),DP2(),i=0;i<=n;++i) t=(1LL*f[s][i]*tot[n-i]+t)%X;//扫一遍求答案
    	return printf("%d
    ",t),0;//输出答案
    }
    
  • 相关阅读:
    作业
    作业
    [转]C语言指针 之 函数指针
    iOS 隐私政策
    微信小程序成长记录(一)
    ios 用信号量控制多个异步网络请求
    ios 利用cocapods创建私有库
    ios 整理获取设备相关信息
    ios_scrollView顶部图片下拉放大
    ios 在项目中使用文字ttf文件
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/LOJ6089.html
Copyright © 2020-2023  润新知