zcmu1166: двойное проникновение брата Чжуна (II)

Ссылка на заголовок: 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;
}

 

рекомендация

отblog.csdn.net/weixin_43911947/article/details/113092941