【Henu ACM Round #12 E】Thief in a Shop

本文详细解析了一类无限物品背包问题的求解方法,通过动态规划寻找满足特定条件的物品组合,实现对不同价值组合的可能性计数。文章还提供了一个具体的代码实现案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【链接】 我是链接,点我呀:)
【题意】


n个物品,每个物品都有无限个。

第i个物品的价格是一样都,都是ai

让你从中选出恰好k个物品

问你选出的物品的总价值 有多少种不同的可能。

【题解】


可以用f[j]表示物品的总价值为j最少需要选多少个物品。
for (int i = 1;i <= n;i++)
for (int j = a[i];j <= k*a[i];j++){
f[j] = min(f[j],f[j-a[i]]+1);
}
然后对于价值j;
如果f[j]==k的话。j就可行?
但是如果f[j]<k呢?
你可以用f[j]个数字凑出来j,但是如果又多一些数字,就没办法凑了。

这个时候。我们可以这样,先把所有的a[i]都减去min{a[i]}
然后再按照相同的方法求出f[i]数组。
这个时候,如果f[j]<=k的话,那么j+imin{a[i]}就一定是可以凑出来的。
因为如果不足k个的话,就用k个min{a[i]}分别加到每一个数字上(没有的数字视为0)
这样就凑成了数字j+i
min{a[i]};
且反过来想。如果j是用原数组中的数字可以凑成的。
那么我们在做的时候,显然j-k*i就会被认为是可以凑成的了。

然后显然也不会说造成多解,误解的情况。因此算法成立。
类似的一道题:我是链接,点我呀:)

【代码】

/*
    1.Shoud it use long long ?
    2.Have you ever test several sample(at least therr) yourself?
    3.Can you promise that the solution is right? At least,the main ideal
    4.use the puts("") or putchar() or printf and such things?
    5.init the used array or any value?
    6.use error MAX_VALUE?
    7.use scanf instead of cin/cout?
    8.whatch out the detail input require
*/
/*
    一定在这里写完思路再敲代码!!!
*/
#include <bits/stdc++.h>
using namespace std;

const int N = 1e3;

int n,k;
int a[N+10],f[N*N+10];

int main(){
    #ifdef LOCAL_DEFINE
        freopen("rush_in.txt", "r", stdin);
    #endif
    ios::sync_with_stdio(0),cin.tie(0);
    cin >> n >> k;
    for (int i = 1;i <= n;i++) cin >> a[i];
    sort(a+1,a+1+n);
    n = unique(a+1,a+1+n) - a - 1;
    for (int i = 2;i <= n;i++) a[i]-=a[1];

    f[0] = 0;
    for (int i = 1;i <= N*N;i++) f[i] = k+1;
    for (int i = 2;i <= n;i++)
        for (int j = a[i];j <= k*a[i];j++)
            f[j] = min(f[j],f[j-a[i]]+1);

    for (int i = 0;i <=N*N;i++)
        if (f[i]<=k){
            cout <<i+k*a[1]<<' ';
        }
    return 0;
}

转载于:https://www.cnblogs.com/AWCXV/p/8361731.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值