CF632E Thief in a Shop
Posted Blogggggg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF632E Thief in a Shop相关的知识,希望对你有一定的参考价值。
题目链接:http://codeforces.com/contest/632/problem/E
题目大意:
从 \(n\) 个不同的数中取 \(k\) 个(可重复取)并加起来,问最多能得到多少种不同的和,从小到大输出所有的和。
(\(1 \le n,k,a_i \le 1000\))
知识点: DP
解题思路:
首先明确一点:对于 \(5s\) 的时限,\(O(1e9)\) 的复杂度是可以过的,因此我们可以来考虑 \(DP\).
具体的方法是:先把 \(a[]\) 数组从小到大排序,将 \(a[0]\) 视为 \(0\),即零点上移 \(a[0]\),则 \(a[]\) 数组中其他的数也要相应地减掉 \(a[0]\)。对这个零点上移 的数组做 \(dp\),使得对每一个和所用的数的个数尽可能少,最后打印答案的时候再将零点复位,则对于需要数的个数小于等于 \(k\) 的和我们都是可以用 \(a[]\) 数组中的 \(k\) 个数取到的(此时 \(0\) 又变回了 \(a[0]\))。
AC代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=1004,inf=0x3f3f3f3f; 4 5 int dp[maxn*maxn]; 6 int a[maxn],da[maxn]; 7 8 int main(){ 9 int n,k; 10 scanf("%d%d",&n,&k); 11 for(int i=0;i<=1000*k;i++) dp[i]=inf; 12 for(int i=0;i<n;i++) scanf("%d",&a[i]); 13 sort(a,a+n); 14 15 for(int i=1;i<n;i++) 16 da[i]=a[i]-a[0]; 17 dp[0]=0; 18 for(int i=1;i<n;i++){ 19 for(int j=0;j<1000*k;j++){ 20 if(dp[j]<inf) 21 dp[j+da[i]]=min(dp[j+da[i]],dp[j]+1); 22 } 23 } 24 25 for(int i=0;i<=1000*k;i++){ 26 if(dp[i]<=k) 27 printf("%d ",i+k*a[0]); 28 }printf("\n"); 29 30 return 0; 31 }
以上是关于CF632E Thief in a Shop的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces 632E Thief in a Shop
CodeForces - 632E Thief in a Shop 完全背包
CodeForces 632E Thief in a Shop
Educational Codeforces Round 9 E. Thief in a Shop NTT
codeforces Educational Codeforces Round 9 E - Thief in a Shop