zcmu1166 : 종 형제의 dp (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는 최소값과 최대 값을 각각 업데이트 할 수 있습니다.

ac 코드

#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