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]を選択しないかの2つのオプションがあります。

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
おすすめ