#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int MAXN = 20;
const int MAXS = 200;
int v[MAXN];
int d[MAXS]; // d[i] : the longest path start from i
int n, s;
int dp(int s)
{
int& ans = d[s];
if(ans != -1) return ans;
ans = -1<<30;
for(int i=0; i<n; i++) {
if(s-v[i] >= 0) {
int di = dp(s-v[i]);
if(di+1 > ans) {
ans = di + 1;
}
}
}
return ans;
}
int dp2(int s)
{
int& ans = d[s];
if(ans != -1) return ans;
ans = 1<<30;
for(int i=0; i<n; i++) {
if(s-v[i] >= 0) {
int di = dp2(s-v[i]);
if(di == -1) continue;
if(ans == -1) ans = di+1;
else if(di+1 < ans) ans = di+1;
}
}
return ans;
}
int mi[MAXS];
int si[MAXS];
int ma[MAXS];
int sa[MAXS];
const int INF = 1<<30;
void dp3()
{
for(int i=0; i<=s; i++) {
mi[i] = INF;
ma[i] = -1*INF;
}
mi[0] = 0;
ma[0] = 0;
for(int i=1; i<=s; i++) {
for(int j=0; j<n; j++) {
if(i >= v[j]) {
if(mi[i] > mi[i-v[j]] + 1) {
mi[i] = mi[i-v[j]] + 1;
si[i] = v[j];
}
if(ma[i] < ma[i-v[j]] + 1) {
ma[i] = ma[i-v[j]] + 1;
sa[i] = v[j];
}
}
}
}
}
void print_min()
{
while(s) {
printf("%d ", si[s]);
s -= si[s];
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
while(scanf("%d%d", &n, &s) == 2) {
for(int i=0; i<n; i++) {
scanf("%d", &v[i]);
}
memset(d, -1, sizeof(d));
d[0] = 0;
//printf("%d\n", dp(s));
//printf("%d\n", dp2(s));
dp3();
printf("min:%d, max:%d\n", mi[s], ma[s]);
printf("min: ");
print_min();
}
return 0;
}
入门经典 例题9-3 硬币问题
最新推荐文章于 2022-09-09 22:49:00 发布