一道算法题目的解法
2007-12-14 14:58
357 查看
一道算法题目的解法
有这样一道算法题目:144张牌放到若干的盒子中, 每个盒子中放10到40张, 问有多少种放法?(不考虑顺序)分析
由144/10=14.4,144/40=3.6可得, 盒子的数量最少为4, 最多为14.假设有n个盒子(4<=n<=14),每个盒子中分别放a1, a2, …, an张牌, 由于不考虑顺序, 不妨设a1<=a2<= … <=an.
然后可以根据盒子的数量进行穷举, 从而得出答案。
考虑到14个盒子的情况, 30^14是个很可观的数字, 为了提高算法的效率, 需要计算ai(1<=i<=n)的最大和最小值。
容易得出
ai最小的情况是
a1=…=ai, ai+1=…=an=40 min(ai)=(144 – (n-i)*40)/i |
a1=min(a1) a2= min(a2)…ai-1= min(ai-1), ai= ai+1=…=an max(ai)=(144-min(a1)-min(a2)-...-min(ai-1))/i |
使用深度优先搜索法的程序如下
#include <stdio.h> #include <stdlib.h> #define COUNT 144 #define MAXVAL 40 #define MINVAL 10 int count = 0; int** minvals; int** maxvals; void get_min_max_vals () { int i; int j; int k; int min, max; int temp; minvals = (int**) malloc (11 * sizeof(int*)); maxvals = (int**) malloc (11 * sizeof(int*)); for (i = 4; i < 15; i++) { minvals[i - 4] = (int*) malloc (i * sizeof(int)); maxvals[i - 4] = (int*) malloc (i * sizeof(int)); for (j = 0; j < i; j++) { min = (COUNT - MAXVAL * (i - j - 1))/(j + 1); minvals[i - 4][j] = min > MINVAL? min: MINVAL; temp = 0; for (k = 0; k < j; k++) { temp += minvals[i - 4][k]; } max = (COUNT - temp) / (i - j); maxvals[i - 4][j] = max > MAXVAL ? MAXVAL: max; } } } void calc (int cur, int total, int* vals) { int i; int from; int last = COUNT; if (cur == total){ for (i = 0; i < cur; i++) { last -= vals[i]; } if ((last >= vals[cur - 1]) && (last <= MAXVAL)) { vals[cur] = last; count ++; } return; } if (0 == cur) { from = minvals[total - 3][cur]; } else { from = minvals[total - 3][cur] > vals[cur - 1] ? minvals[total - 3][cur]: vals[cur - 1]; } for (i = from; i <= maxvals[total - 3][cur]; i++) { vals[cur] = i; calc (cur + 1, total, vals); } } int main() { int j; int* vals; int totalcount; get_min_max_vals(); for (j = 4; j < 15; j++) { count = 0; vals = (int*) malloc (j * sizeof(int)); calc (0, j - 1, vals); printf ("%d boxes: count=%d/n",j, count); totalcount += count; free(vals); } printf ("total=%d/n", totalcount); for (j = 0; j < 11; j++) { free(minvals[j]); free(maxvals[j]); } free(minvals); free(maxvals); return 0; } |
相关文章推荐
- 转:算法合集之《从一道题目的解法试谈网络流的构造与算法》
- 数学与程序的结合——一道游戏题目的快速解法
- 【白话经典算法系列之十一】一道有趣的GOOGLE面试题 --【解法2】
- 【白话经典算法系列之十一】一道有趣的GOOGLE面试题 --【解法2】 .
- 一道算法题目的思考
- 一道面试题目解法
- 每天一道算法题目(20)——复杂链表的拷贝
- 一道多路归并算法分析的题目
- 一道算法题解法,笑出声
- 每天一道算法题目(18)——取等长有序数组的上中位数和不等长有序数组的第k小的数
- 一道算法题的一种O(n)解法
- 白天看到的一道算法题目,应该是平衡二叉树方面的
- 一道算法题的一种O(n)解法
- 一道微软算法题的java解法
- 每天一道算法题目(20)——复杂链表的拷贝
- 每天一道算法题目(17)——二叉树的子结构
- 一道简单题目的复杂算法
- 百度一道关于算法的面试题目
- LeetCode上面一道算法题目:79. Word Search
- 关于一道题目解法