제목 링크 : 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;
}