Thief in a Shop
题意:
你有
n
n
n种商品,每种商品有无数个和单价,你只能买
k
k
k个商品,让你从小到大输出所有可能的价格。
分析:
完全背包。一开始总是会搞浑数量和价格。
我们设
d
p
i
dp_i
dpi表示的价格为
i
i
i的最小商品数,不难得出转移方程:
d
p
[
i
]
=
m
i
n
(
d
p
[
i
]
,
d
p
[
i
−
a
[
j
]
]
+
1
)
dp[i] = min(dp[i], dp[i - a[j]] + 1)
dp[i]=min(dp[i],dp[i−a[j]]+1)
然后我们对单价进行排序,然后所有的商品都减去
a
1
a_1
a1,对于所有
d
p
[
i
]
≤
k
dp[i] \le k
dp[i]≤k的价格就是
k
×
a
[
1
]
+
i
k \times a[1] + i
k×a[1]+i。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 5;
int a[maxn], dp[maxn * maxn];
int main() {
int n, k;
memset(dp, 0x3f, sizeof(dp));
dp[0] = 0;
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
sort(a + 1, a + 1 + n);
for (int i = 2; i <= n; i++) a[i] -= a[1];
int m = a[n] * k;
for (int i = 2; i <= n; i++)
for (int j = a[i]; j <= m; j++)
dp[j] = min(dp[j], dp[j - a[i]] + 1);
n = a[1] * k;
for (int i = 0; i <= m; i++) if (dp[i] <= k) printf("%d ", i + n);
puts("");
return 0;
}