• codeforces632E 小偷与商店


    题面:

    题目描述

    一个小偷向一家商店走去,像往常一样,他带着他的幸运背包。背包可以装 k 件商品。在商店里有 n 种商品,每种商品有无数件,商品价格为 a_iai。小偷比较贪心,他总会选择 k 件商品装满背包(同一种商品可以多次装入)。
    请找到选择 k 件商品的所有可能价值。

    输入格式

    第一行两个整数 n, k,表示 n 种商品,背包容量 k。
    第二行 n 个整数 ai,表示 1 到 n 种商品的价格 ai

    输出格式

    输出所有可能被盗商品的总价值,由一个空格隔开。这些数字应按升序排列。

    样例1

    输入

    3 2
    1 2 3
    

    输出

    2 3 4 5 6
    

    样例2

    输入

    5 5
    1 1 1 1 1

    输出

    5
    

    样例3

    输入

    3 3
    3 5 11

    输出

    9 11 13 15 17 19 21 25 27 33

    数据范围

    对于 30%的数据,1 ≤ n, k ≤ 100,1 ≤ ai≤ 100;
    对于 100%的数据,1 ≤ n, k ≤ 1000,1 ≤ ai≤ 1000。

    限制

    2s, 256M


    还是有点意思的,一开始只做了n^4的方法。正解是将所有数排序减去最小数之后背包,最后判断个数是否小于K直接加上K*min(最小价值)就行了,因为减去的可以用最小值去补,最终一定能补到K个,复杂度是(n^3)。

    代码如下:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 #define LL long long 
     7 using namespace std;
     8 template <class _T> inline void read(_T &_x){
     9     int _t;bool _flag=false;
    10     while((_t=getchar())!='-'&&(_t<'0'||_t>'9'));
    11     if(_t=='-')_flag=true,_t=getchar();_x=_t-'0';
    12     while((_t=getchar())>='0'&&_t<='9')_x=_x*10+_t-'0';
    13     if(_flag)_x=-_x;
    14 }
    15 const int maxn=505;
    16 int n,x,ct,K,lm,a[maxn];
    17 int dp[maxn*maxn];
    18 bool vis[maxn];
    19     read(n),read(K);
    20     for(register int i=1;i<=n;++i){
    21         read(x);
    22         if(!vis[x]){ 
    23             vis[x]=1;
    24             a[++ct]=x;
    25         }
    26     }
    27     n=ct;
    28     sort(a+1,a+n+1);
    29     for(int i=2;i<=n;++i){
    30         a[i]-=a[1];
    31     }
    32     lm=a[n];
    33     lm=lm*K;
    34     memset(dp,0x3f3f,sizeof dp);
    35     dp[0]=0;
    36     for(register int i=n;i>=2;--i){
    37         for(register int j=a[i];j<=lm;++j)
    38             dp[j]=min(dp[j],dp[j-a[i]]+1);
    39     }
    40     if(lm==0)printf("0");
    41     else {
    42         for(int i=0;i<=lm;++i)
    43             if(dp[i]<=K)printf("%d ",i+a[1]*K);
    44     }
    45     return 0;
    46 }
    47  
  • 相关阅读:
    【转】linux root用户ifconfig报command not found
    xp系统word2007升级到2010.若失败,可向以下几个方向考虑
    ORACLE 检查数据库表中是否存在不规范字 段的语句参考.sql
    oracle关于分区相关操作
    表大小查看
    【收藏】表分区
    【收藏】Linux下tomcat内存配置
    oracle分页
    首测!阿里云盘终于来了,扫码获取邀请码
    MYSQL 删除表中重复数据
  • 原文地址:https://www.cnblogs.com/AT-HENS/p/7767339.html
Copyright © 2020-2023  润新知