• Loj #6089. 小 Y 的背包计数问题


    link : https://loj.ac/problem/6089

    大致就是第i个物品有i个且每个的体积是i,问填满体积为N的背包的方案数。

    首先可以发现的是 > sqrt(N) 的物品是用不完的,所以可以看成完全背包。

    但直接完全背包的话因为复杂度是 O((N-sqrt(N))*N) 的 ,其实就是 O(N^2),肯定会挂。

    但是我们考虑一个性质:最后背包中的物品最多只能有sqrt(N)件,并且每件的起始体积都是sqrt(N)+1。

    所以我们就设 g[i][j] 为选了i件物品,总体积为j的方案数。

    转移就是 g[i][j] = g[i-1][j-(sqrt(N)+1)] + g[i][j-i]  ,这就是考虑每次多加一个初始体积物品或者给每个物品都+1的体积。

    因为这样能保证后加的物品最后的体积一定<=前加的,所以符合无序性,是正确的。

    至于<=sqrt(N)的物品直接暴力多重背包就行了 (当然前提是对于每个物品你的多重背包复杂度是 O(N)的,就是对物品体积的同余系下相同的元素一起处理)

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 100005
    using namespace std;
    const int ha=23333333;
    int now,pre,f[2][maxn],n,S;
    int g[2][maxn],block[maxn];
    
    inline int add(int x,int y){
    	x+=y;
    	return x>=ha?x-ha:x;
    }
    
    inline void dp_big(){
    	g[0][0]=1,now=0,block[0]++;
    	
    	for(int i=1;i*S<=n;i++){
    		pre=now,now^=1;
    		fill(g[now],g[now]+i,0);
    		for(int j=i;j<=n;j++){
    			g[now][j]=g[now][j-i];
    			if(j>=S) g[now][j]=add(g[now][j],g[pre][j-S]);
    			
    			block[j]=add(block[j],g[now][j]);
    		}
    	}
    }
    
    inline void dp_small(){
    	now=0,f[0][0]=1;
    	for(int i=1,res;i<S;i++){
    		pre=now,now^=1,res=i*(i+1);
    		for(int j=0;j<i;j++)
    		    for(int u=j,tmp=0;u<=n;u+=i){
    		    	tmp=add(tmp,f[pre][u]);
    		    	if(u-res>=0) tmp=add(tmp,ha-f[pre][u-res]);
    		    	f[now][u]=tmp;
    			}
    	}
    }
    
    inline void output(){
    	int ans=0;
    	for(int i=0;i<=n;i++) ans=add(ans,f[now][i]*(ll)block[n-i]%ha);
    	printf("%d
    ",ans);
    }
    
    int main(){
    	scanf("%d",&n),S=sqrt(n)+1;
    	dp_big();
    	dp_small();
    	output();
    	return 0;
    }
    

      

  • 相关阅读:
    PostgreSQL pg_hba.conf 文件简析
    Centos 查看端口占用情况
    Nginx 从0开始学
    windows 杀死端口号对应进程
    MyBatis基础-05-缓存
    MyBatis基础-04-动态sql
    MyBatis基础-02
    SpringMVC基础-14-SpringMVC与Spring整合
    SpringMVC基础-13-SpringMVC运行流程
    SpringMVC基础-12-异常处理
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8524849.html
Copyright © 2020-2023  润新知