zoukankan      html  css  js  c++  java
  • LOJ #6089. 小 Y 的背包计数问题

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


    神仙题啊orz。

    首先把数分成(<=sqrt n)的和(>sqrt n)的两部分。

    (>sqrt n)的部分因为最多选(sqrt n)个数,所以数量就没有卵用了。然后就用完全背包的一个常见套路(?)可以对一个空的序列整体+1或者在最左边加上一个(sqrt n+1),这个操作序列和完全背包的选择方案一一对应。感性理解一下是对的emmmm,复杂度(O(nsqrt n))

    (<=sqrt n)的部分只有(sqrt n)个数,就可以多重背包做,然后用剩余系优化。
    剩余系就是说多重背包方案的转移方程是(f[i][j]=sum_{k=1}^{i}f[i-1][j-ki])这个样子的

    可以发现转移过来的j都和原来的j同余(( ext{mod } i))

    对于每一个( ext{mod }i)的余数做一个f的前缀和,转移过来的一定是连续的一段

    orz

    #include<bits/stdc++.h>
    #define il inline
    #define vd void
    typedef long long ll;
    il int gi(){
    	int x=0,f=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){
    		if(ch=='-')f=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    	return x*f;
    }
    #define mod 23333333
    ll f[320][100010];
    ll h[100010],s[100010];
    int main(){
    	int n=gi(),m=int(sqrt(n));
    	f[0][0]=1;s[0]=1;
    	for(int i=1;i<=m;++i)
    		for(int j=0;j<=n;++j){
    			if(j>i)f[i][j]+=f[i][j-i];
    			if(j>m)f[i][j]+=f[i-1][j-m-1];
    			f[i][j]%=mod;
    			s[j]=(s[j]+f[i][j])%mod;
    		}
    	memset(f,0,sizeof f);f[0][0]=1;
    	for(int i=1;i<=m;++i){
    		for(int j=0;j<i;++j){
    			int t=0;
    			for(int k=j;k<=n;k+=i)h[++t]=f[i-1][k];
    			for(int k=2;k<=t;++k)h[k]=(h[k]+h[k-1])%mod;
    			for(int k=j,tot=0;k<=n;k+=i){
    				++tot;
    				f[i][k]=(f[i][k]+h[tot]-h[std::max(0,tot-i-1)]+mod)%mod;
    			}
    		}
    	}
    	ll ans=0;
    	for(int i=0;i<=n;++i)ans+=s[i]*f[m][n-i]%mod;
    	printf("%lld
    ",ans%mod);
    	return 0;
    }
    
  • 相关阅读:
    LeetCode Single Number
    Leetcode Populating Next Right Pointers in Each Node
    LeetCode Permutations
    Leetcode Sum Root to Leaf Numbers
    LeetCode Candy
    LeetCode Sort List
    LeetCode Remove Duplicates from Sorted List II
    LeetCode Remove Duplicates from Sorted List
    spring MVC HandlerInterceptorAdapter
    yum
  • 原文地址:https://www.cnblogs.com/xzz_233/p/9674940.html
Copyright © 2011-2022 走看看