UVA165
来源:互联网 发布:软件质量保证的过程 编辑:程序博客网 时间:2024/05/22 14:16
连续邮资问题,题目的意思就是你可以贴h张邮票,并且可供选择的面额有k种。k + h 《= 9;问连续面额最多有多少。。
样例3 2
指可以贴三张,有两种面额,面额是1 4的话,可以组成1,2.3,4,5,6,8,9,12,连续的最大到6个,而面额是 1 ,3时,可以组成 1,2,3,4,5,6,7,9连续的最大到7个。
我们要做的就是找到面额为多少时,连续的最大,最大为多少。
做法是用一个数组stamp 来存面额是多少,然后用数组m[ i ] 来存,当面额数为 i 时 最大连续到几。。
现在开始分析:
首先可以确定,第一种面额一定是 1 ,没有 1 很多数都凑不出来,不能连续。那么只有这一种面额时,最大连续到 h ,这很好理解,h张全是1 ,当然那 m [ 0 ] 也就是h了;
那么第二种面额该选哪个? 可以循环遍历,但题目没有给出限制,总不能从1试到无穷大。
现在m数组就用上了,第 i 张的面额大小范围就是从前一张大小加1(这点很明确) ,到m [ i ] 为止 。为什么呢,可以试想,如果你前面两张最多连续到了6了,比如是1 2,可以组成 1,2,3,4,5, 6。那么第三张最多也只能是7 ,因为如果第三张是8 ,你前两张最多到 6,那你还有可能组成7 吗? 所以就断了,这也是m数组记录前n张最多组成连续到几的目的。
现在要对每一种面额数量进行dfs(),为了得出每一种面额数量连续的最大值,当然最后结果只要取 m [ k - 1]即可,前面的递归是为了求出每一次循环的范围。。
#include<cstring> #include<cstdio>#include<cstdlib>#include<iostream>using namespace std;const int N = 200;int h, k;int res[N], stamp[N], m[N];int fina;bool flag[N];void dfs(int cur, int n, int sum){ if(cur >= h){ flag[sum] = true; return; }flag[sum] = true; for(int i = 0; i <= n; i++){ dfs(cur+1, n, sum+stamp[i]); }}void search(int cur){ if(cur >= k){ if(m[cur-1] > fina){ fina = m[cur-1]; memcpy(res, stamp, sizeof(stamp)); } return ; } for (int i = stamp[cur - 1] + 1; i <= m[cur - 1] + 1; i++){ memset(flag, 0, sizeof(flag)); stamp[cur] = i; dfs(0, cur, 0); int num = 0;int j = 1; while(flag[j++]) num++; m[cur] = num; search(cur+1); }}int main(){ while(scanf("%d %d", &h, &k), h+k){ stamp[0] = 1; m[0] = h; fina = -1; search(1); for(int i = 0; i < k; i++) printf("%3d", res[i]); printf(" ->%3d\n", fina); } return 0;}
0 0
- UVA165
- uva165
- UVA165
- uva165 - stamps(邮票)
- [回溯]Stamps UVA165
- e5-4 uva165
- UVA165连续邮资问题
- [TLE剪枝]uva165邮票连续值
- android:点击左边按钮增加数值,点击右边按钮减小数值
- 代码坏味道之夸夸其谈的未来性
- Failure [INSTALL_FAILED_OLDER_SDK] Android-L
- 组队赛5 - 2014.8.10
- MVN 添加本地Jar
- UVA165
- java中关于Map的九大问题
- zoj 2788 Panic Room (最小割)
- 《一步一脚印 90后程序员》16
- 一分钟经理答案
- 工作问题之自定义confirm功能框
- 以太网,局域网,万维网
- 七个受用一生的心理寓言(成长的寓言:做一棵永远成长的苹果树)
- 贝塞尔曲线