搜索/动规-邮票面值设计

这道题非常暴力,数据非常水。

根据题目 N+K <= 40 ,我的程序在 N = 5, K = 6 时就死掉了,但提交之后 0s 通过……

 1 #include <stdio.h>
 2 #include <algorithm>
 3 
 4 typedef long long LL;
 5 
 6 const long long INF = 9999999999999LL;
 7 
 8 LL N, K, ans;
 9 LL f[43*43], res[43], ans_arr[43];
10 
11 inline void _cpy(LL *t1, LL *t2)
12 {
13     for (LL i = 1; i <= K; ++i) t1[i] = t2[i];
14     return;
15 }
16 
17 LL get_mx(LL t)
18 {
19     LL limit = res[t] * N, i, j;
20     for (i = 1; i <= limit; ++i) f[i] = INF;
21     f[0] = 0;
22     for (i = 1; i <= limit; ++i) {
23         for (j = 1; j <= t && i - res[j] >= 0; ++j)
24             f[i] = std::min(f[i], f[i - res[j]] + 1);
25         if (f[i] > N) return i-1;
26     }
27     return limit;
28 }
29 
30 void dfs_K(LL step)
31 {
32     LL tmp = get_mx(step - 1);
33     if (step == K + 1) {
34         if (ans < tmp) ans = tmp, _cpy(ans_arr, res);
35         return;
36     }
37     for (LL i = res[step - 1] + 1; i <= tmp + 1; ++i)
38         res[step] = i, dfs_K(step + 1);
39     return;
40 }
41 
42 int main()
43 {
44     scanf("%lld%lld", &N, &K);
45     res[1] = 1;
46     dfs_K(2);
47     for (LL i = 1; i < K; ++i) printf("%lld ", ans_arr[i]);
48     printf("%lld
MAX=%lld
", ans_arr[K], ans);
49     return 0;
50 }
View Code

题目

NKOJ1152

邮票面值设计(NOIP)
时间限制 : 20000 MS   空间限制 : 65536 KB
问题描述

给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX,使在1~MAX之间的每一个邮资值都能得到。

例如,N=3,K=2,如果面值分别为1分、4分,则在1分~6分之间的每一个邮资值都能得到(当然还有8分、9分和12分);如果面值分别为1分、3分,则在1分~7分之间的每一个邮资值都能得到。可以验证当N=3,K=2时,7分就是可以得到的连续的邮资最大值,所以MAX=7,面值分别为1分、3分。

输入格式

两个整数 N和K

输出格式

第一行,K个空格间隔的整数,表示K种邮票的面值
第二行,一个整数,表示能够得到的最大MAX值

样例输入

3 2

样例输出

1 3 
MAX=7

原文地址:https://www.cnblogs.com/ghcred/p/8544348.html