Ссылка на заголовок: https://acm.zcmu.edu.cn/JudgeOnline/problem.php?id=1166
Тема
Монеты n, номинал ai, каждый вид неограничен. Затем укажите s, сколько монет можно использовать, чтобы общая номинальная стоимость была точно равна s. Выведите минимальное и максимальное значения количества монет.
Идеи
Выберите предметы, количество не ограничено, тогда это полный рюкзак .
dp1 [i] оба представляют количество монет с номиналом i. Чтобы сделать общую номинальную стоимость равной j, есть два варианта: выбрать текущий a [i] или не выбирать a [i].
Если выбран a [i], то останется только sa [i], если dp1 [ja [i]] == inf или dp2 [ja [i]] == - 1, это означает, что предыдущие монеты не могут быть собраны в ja [i], напротив, число dp [ja [i]] + 1, где 1 - текущая выбранная монета. dp1, dp2 могут обновлять минимальное и максимальное значения соответственно.
код переменного тока
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1e4 + 10;
const int inf = 0x3f3f3f3f;
int a[105], dp1[maxn], dp2[maxn];
int main(){
int n, s;
while(~scanf("%d%d", &n, &s)){
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
memset(dp1, inf, sizeof(dp1));
memset(dp2, -1, sizeof(dp2));
dp1[0] = dp2[0] = 0;
for(int i = 1; i <= n; i ++){
for(int j = a[i]; j <= s; j ++){
if(dp1[j - a[i]] != inf)
dp1[j] = min(dp1[j], dp1[j - a[i]] + 1);
if(dp2[j - a[i]] != -1)
dp2[j] = max(dp2[j], dp2[j - a[i]] + 1);
}
}
if(dp1[s] == inf) dp1[s] = -1;
printf("%d %d\n", dp1[s], dp2[s]);
}
return 0;
}