JZOJ4681. 选择

来源:互联网 发布:软件接口测试视频教程 编辑:程序博客网 时间:2024/06/05 22:54

原题:CF 632E

题目大意

n个盒子,每个盒子里有无数个球,每个盒子里球的价格为ai,现在要买k个球,求所有可能的付钱数。

Data Constraint
n,m500

题解

先把所有的价格减去价格的最小值。这样做有什么好处?原本我们为了凑到某个数需要强制恰好取k次,减去最小值以后一个数就可以变成在k次内取到,次数不足的就视为取最小值。
f[i]表示达到i所需要的最小次数,如果一个数x满足f[x]k,那么就有一个答案x+kmin
时间复杂度:O(n^3)

SRC

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std ;#define N 500 + 10#define M 250000 + 10int f[M] , a[N] ;int n , k , sum , maxv , minv = 0x7FFFFFFF ;int main() {    scanf( "%d%d" , &n , &k ) ;    for (int i = 1 ; i <= n ; i ++ ) {        scanf( "%d" , &a[i] ) ;        minv = min( minv , a[i] ) ;    }    sort( a + 1 , a + n + 1 ) ;    for (int i = 1 ; i <= n ; i ++ ) {        a[i] -= minv ;        maxv = max( maxv , a[i] ) ;    }    sum = k * maxv ;    memset( f , 63 , sizeof(f) ) ;    f[0] = 0 ;    for (int i = 1 ; i <= n ; i ++ ) {        if ( a[i] == a[i-1] ) continue ;        for (int j = a[i] ; j <= sum ; j ++ ) f[j] = min( f[j] , f[j-a[i]] + 1 ) ;    }    for (int i = 0 ; i <= sum ; i ++ ) {        if ( f[i] <= k ) printf( "%d " , i + minv * k ) ;    }    return 0 ;}

以上.

1 0
原创粉丝点击