• loj6089 小Y的背包计数问题


    Description

    ( ext{Y}) 有一个大小为 (n) 的背包,并且小 ( ext{Y})(n) 种物品。

    对于第 (i) 种物品,共有 (i) 个可以使用,并且对于每一个 (i) 物品,体积均为 (i)

    求小 ( ext{Y}) 把该背包装满的方案数为多少,答案对于 (23333333) 取模。

    定义两种不同的方案为:当且仅当至少存在一种物品的使用数量不同。

    Solution

    考虑将物品分为两类,一类是小于等于 (sqrt{N}) 的物品,另一类式大于 (sqrt{N}) 的物品。

    小于等于 (sqrt{N}) 的物品,直接跑一个多重背包,前缀和优化即可。

    大于 (sqrt{N}) 的物品,由于每种物品不可能放入超过 (sqrt{N}) 个,因此可以视为无限个物品,跑一遍完全背包。

    但是直接跑完全背包是 (O(N^2)) 的,转移时有一个技巧,由于这里的物品体积都是连续的,所以转移可以分两种,一是给全部物品的体积加 (1),二是插入一个 (sqrt{N}+1) 体积的物品,可以保证,这样一定能够构造出所有的方案。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int _ = 1e5 + 10;
    const int __ = 320 + 5;
    const ll mod = 23333333;
    int N, M;
    ll f[_], g[__][_], sum[_], ans;
    
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("backpack.in", "r", stdin);
    	freopen("backpack.out", "w", stdout);
    #endif
    	scanf("%d", &N);
    	M = sqrt(N);
    	f[0] = 1;
    	for (int i = 1; i <= M; ++i) {
    		for (int j = 0; j < i; ++j) {
    			int now = 0;
    			for (int k = j; k <= N; k += i) sum[++now] = f[k];
    			for (int k = 1; k <= now; ++k) sum[k] = (sum[k] + sum[k - 1]) % mod;
    			for (int k = j, p = 1; k <= N; k += i, ++p)
    				f[k] = (sum[p] - sum[max(0, p - i - 1)] + mod) % mod;
    		}
    	}
    	memset(sum, 0, sizeof(sum));
    	g[0][0] = 1;
    	sum[0] = 1;
    	for (int i = 1; i <= M; ++i) {
    		for (int j = min(i, M + 1); j <= N; ++j) {
    			if (j >= i) g[i][j] = (g[i][j] + g[i][j - i]) % mod;
    			if (j >= M + 1) g[i][j] = (g[i][j] + g[i - 1][j - M - 1]) % mod;
    			sum[j] = (sum[j] + g[i][j]) % mod;
    		}
    	}
    	for (int i = 0; i <= N; ++i) ans = (ans + f[i] * sum[N - i] % mod) % mod;
    	printf("%lld
    ", ans);
      return 0;
    }
    
  • 相关阅读:
    把握人生12种财富:让商人更自信
    英语谚语的汉译
    心胸有多大,事业才可能有多大
    想成领袖?先瞄准老板身边的位置
    绝对挑战:如何来提高自己的影响力?
    送给创业的朋友:落入坑洞的猎人
    跨越危机,塑造完美的职业生涯(三)
    如果一个男人真的爱你
    跨越危机,塑造完美的职业生涯(一)
    来自最伟大推销员的成功金句
  • 原文地址:https://www.cnblogs.com/newbielyx/p/12181312.html
Copyright © 2020-2023  润新知