搜索/动规-邮票面值设计
这道题非常暴力,数据非常水。
根据题目 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\nMAX=%lld\n", ans_arr[K], ans); 49 return 0; 50 }
题目
NKOJ1152
邮票面值设计(NOIP) | |
|
问题描述
给定一个信封,最多只允许粘贴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