UVa 165 - Stamps 解题报告(暴力)
来源:互联网 发布:上海银行 淘宝金卡 编辑:程序博客网 时间:2024/05/29 03:47
Stamps
The government of Nova Mareterrania requires that various legal documents have stamps attached to them so that the government can derive revenue from them. In terms of recent legislation, each class of document is limited in the number of stamps that may be attached to it. The government wishes to know how many different stamps, and of what values, they need to print to allow the widest choice of values to be made up under these conditions. Stamps are always valued in units of $1.
This has been analysed by government mathematicians who have derived a formula for n(h,k), where h is the number of stamps that may be attached to a document, k is the number of denominations of stamps available, and n is the largest attainable value in a continuous sequence starting from $1. For instance, if h=3, k=2 and the denominations are $1 and $4, we can make all the values from $1 to $6 (as well as $8, $9 and $12). However with the same values of h and k, but using $1 and $3 stamps we can make all the values from $1 to $7 (as well as $9). This is maximal, so n(3,2) = 7.
Unfortunately the formula relating n(h,k) to h, k and the values of the stamps has been lost--it was published in one of the government reports but no-one can remember which one, and of the three researchers who started to search for the formula, two died of boredom and the third took a job as a lighthouse keeper because it provided more social stimulation.
The task has now been passed on to you. You doubt the existence of a formula in the first place so you decide to write a program that, for given values of h and k, will determine an optimum set of stamps and the value of n(h,k).
Input
Input will consist of several lines, each containing a value for h and k. The file will be terminated by two zeroes (0 0). For technical reasons the sum of h and k is limited to 9. (The President lost his little finger in a shooting accident and cannot count past 9).
Output
Output will consist of a line for each value of h and k consisting of the k stamp values in ascending order right justified in fields 3 characters wide, followed by a space and an arrow (->
) and the value of n(h,k) right justified in a field 3 characters wide.
Sample input
3 20 0
Sample output
1 3 -> 7
解题报告:经典题。打表过的……如下
string answer[] ={" 1 -> 1"," 1 2 -> 2"," 1 2 3 -> 3"," 1 2 3 4 -> 4"," 1 2 3 4 5 -> 5"," 1 2 3 4 5 6 -> 6"," 1 2 3 4 5 6 7 -> 7"," 1 2 3 4 5 6 7 8 -> 8"," 1 -> 2"," 1 2 -> 4"," 1 3 4 -> 8"," 1 3 5 6 -> 12"," 1 3 5 7 8 -> 16"," 1 2 5 8 9 10 -> 20"," 1 2 5 8 11 12 13 -> 26"," 1 -> 3"," 1 3 -> 7"," 1 4 5 -> 15"," 1 4 7 8 -> 24"," 1 4 6 14 15 -> 36"," 1 3 7 9 19 24 -> 52"," 1 -> 4"," 1 3 -> 10"," 1 5 8 -> 26"," 1 3 11 18 -> 44"," 1 3 11 15 32 -> 70"," 1 -> 5"," 1 4 -> 14"," 1 6 7 -> 35"," 1 4 12 21 -> 71"," 1 -> 6"," 1 4 -> 18"," 1 7 12 -> 52"," 1 -> 7"," 1 5 -> 23"," 1 -> 8",};
百度了一下其他方法,这篇博客说的不错。http://blog.csdn.net/shuangde800/article/details/7755452
参照上面的博客优化了一下之前的方法。每次枚举新的邮票时,邮票大小可以设定为当前最大邮票+1,到当前所有邮票有h张时可以组成的最大连续值+1。这样不会出现不连续,并且减少了盲目枚举,速度快了很多。换句话说,枚举的思路很好。代码如下:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <vector>#include <map>#include <set>#include <string>#include <iomanip>using namespace std;#define ff(i, n) for(int i=0;i<(n);i++)#define fff(i, n, m) for(int i=(n);i<=(m);i++)#define dff(i, n, m) for(int i=(n);i>=(m);i--)#define bit(n) (1LL<<(n))typedef long long LL;typedef unsigned long long ULL;void work();int main(){#ifdef ACM// freopen("in.txt", "r", stdin);#endif // ACM work();}/***************************************************/int ans;int res[11];int n, k;int stamp[11];int up;int id;int vis[222];void dfs1(int sta, int has, int sum){ vis[sum] = id; if(has == n) return; fff(i, sta, up) dfs1(i, has+1, sum + stamp[i]);}void dfs2(int sta, int has){ ++id; up = has-1; dfs1(0, 0, 0); int t = 0; while(vis[t+1] == id) t++; if(has == k) { if(ans < t) { ans = t; memcpy(res, stamp, sizeof(stamp)); } return; } fff(i, sta, t+1) { stamp[has] = i; dfs2(sta+1, has+1); }}void work(){ while(scanf("%d%d", &n, &k) == 2 && (n||k)) { ans = 0; stamp[0] = 1; dfs2(2, 1); ff(i, k) printf("%3d", res[i]); printf(" ->%3d\n", ans); }}
另外一种方法就是每次枚举组成1到val值所需要的最少邮票数,使用动态规划优化统计部分。效率上会好很多。代码如下:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <vector>#include <map>#include <set>#include <string>#include <iomanip>using namespace std;#define ff(i, n) for(int i=0;i<(n);i++)#define fff(i, n, m) for(int i=(n);i<=(m);i++)#define dff(i, n, m) for(int i=(n);i>=(m);i--)#define bit(n) (1LL<<(n))typedef long long LL;typedef unsigned long long ULL;void work();int main(){#ifdef ACM// freopen("in.txt", "r", stdin);#endif // ACM work();}/***************************************************/int ans;int res[11];int n, k;int stamp[11];int y[222];void dfs2(int sta, int has, int curMax){ if(has == k) { if(ans < curMax) { ans = curMax; ff(i, k) res[i] = stamp[i]; } return; } int tmp[222]; memcpy(tmp, y, sizeof(y)); fff(i, sta+1, curMax+1) { ff(j, sta*n) if(y[j]<n) fff(num, 1, n-y[j]) y[j+i*num] = min(y[j+i*num], y[j]+num); int t = curMax; while(y[++t] <= n); stamp[has] = i; dfs2(i, has+1, t-1); memcpy(y, tmp, sizeof(tmp)); }}void work(){ while(scanf("%d%d", &n, &k) == 2 && (n||k)) { ans = 0; stamp[0] = 1; fff(i, 0, n) y[i] = i; fff(i, n+1, 200) y[i] = 20; dfs2(1, 1, n); ff(i, k) printf("%3d", res[i]); printf(" ->%3d\n", ans); }}
- UVa 165 - Stamps 解题报告(暴力)
- UVa 669 - Defragment 解题报告(暴力)
- UVa 140 - BandWidth 解题报告(暴力)
- UVa 225 - Golygons 解题报告(暴力)
- UVa 10317 Equating Equations 解题报告(暴力)
- UVa 1533 Moving Pegs 解题报告(暴力+码力)
- UVa 110 Meta-Loopless Sorts 解题报告(暴力)
- UVa 120 - Stacks of Flapjacks 解题报告(暴力)
- UVa 269 Counting Patterns 解题报告(暴力)
- UVa 387 - A Puzzling Problem 解题报告(暴力)
- uva 165 Stamps (DFS)
- uva 165 Stamps (回溯)
- POJ 1010 解题报告 STAMPS
- POJ 1010 STAMPS 解题报告
- UVa 10318 Security Panel 解题报告(暴力,中途相遇法)
- uva - 165 - Stamps(回溯、模拟)
- UVa 165 - Stamps(连续邮资问题)
- uva 165 - Stamps
- ZOJ 4257 Most Powerful
- button 修改 title 和 image偏移量
- Hadoop_WordCount示例_运行详解
- 产品经理入职后要做的12件事
- poj 1088 滑雪
- UVa 165 - Stamps 解题报告(暴力)
- ASP.NET Cookie的存储与读取
- HDU - 2276 Kiki & Little Kiki 2
- vc++取得系统信息,并实时刷新
- MyEclipse,Eclipse安装findBugs插件技巧
- 完美框架
- hdu-2018-母牛的故事
- Spring 父子容器(Spring配置的一个坑)
- UVA - 10055 Hashmat the brave warrior