人民币组成问题&八皇后问题&乒乓球比赛问题
例题1:
现有五种面值的人民币若干,分别为1元、10元、20元、50元、100元,需凑出2017元人民币,假设五种面值人民币数量足够多,问一共有多少种组成方式,并求出最优解。
问题分析:
(1)研究分析得出,可以利用动态规划的方法解决此问题,动态规划的本质是将原问题分解为同性质的若干相同子结构,在求解最优值的过程中将子结构的最优值记录到一个表中以避免有时会有大量的重复计算。
(2)首先要知道所有不大于该钱数的面值。
(3)对于每种面值的硬币,求出当选择一个该面值的硬币时所需的硬币数。
(4)当选择一个硬币后,所需硬币数+1。
(5)进行遍历,筛选出符合条件的结果,并求出最优解。
代码实现:
C++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include int money() { int count = 0; for(int i1 = 0;i1<2017/1;i1++) { for(int i2 = 0;i2<2017/10;i2++) { if(i1*1+i2*10>2017) { continue; } for(int i3 = 0;i3<2017/20;i3++) { if(i1*1+i2*10+i3*20>2017) { continue; } for(int i4 = 0;i4<2017/50;i4++) { if(i1*1+i2*10+i3*20+i4*50>2017) { continue; } for(int i5 = 0;i5<2017/100;i5++) { if(i1*1+i2*10+i3*20+i4*50+i5*100==2017) { count++; printf("1:%d,10:%d,20:%d,50:%d,100:%d",i1,i2,i3,i4,i5); } } } } } } return count; } int main() { money(); return 0; } |
例题2:
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
由于8个皇后的任意两个不能处在同一行,那么肯定是每一个皇后占据一行。于是我们可以定义一个数组queen[8],表示皇后的列号。先把数组queen[]的8个数字分别用0~7初始化,接下来就是对数组queen[]做全排列。因为我们是用不同的数字初始化数组,所以任意两个皇后肯定不同列。我们只需要判断每一个排列对应的8个皇后是不是在同一行或同一对角线上即可。
代码实现:
C++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include #include #define max 8 int queen[max]; int count = 0; void show(); int check(int n) // 检查当前列能否放置皇后 { int i; for(i = 0; i < n; i++) { if(queen[i] == queen[n] || abs(queen[i] - queen[n]) == (n - i)) // 检查横排和对角线上是否可以放置皇后 { return 1; } } return 0; } void put(int n) // 回溯尝试皇后位置,n为横坐标 { int i; for(i = 0; i < max; i++) { queen[n] = i; // 将皇后摆到当前循环到的位置 if(!check(n)) { if(n == max - 1) { show(); // 如果全部摆好,则输出所有皇后的坐标 } else { put(n + 1); // 否则继续摆放下一个皇后 } } } } void show() // 输出所有皇后的坐标 { int i; for(i = 0; i < max; i++) { printf("(%d,%d) ", i, queen[i]); } printf("\n"); count++; } int main() { put(0); // 从横坐标为0开始依次尝试 printf("%d", count); printf("\n"); return 0; } |
例题3:
两个乒乓球队进行比赛,各出3人,甲队为A,B,C3人,乙队为X,Y,Z3人,以抽签决定比赛名单。有人向队员打听比赛名单,A说他不和X比,C说他不和X,Z比,请程序员找出赛手名单。(枚举法)
代码实现:
C++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include void PPmatch() { for(char a = 'x';a<='z';a++) { for(char b = 'x';b<='z';b++) { for(char c = 'x';c<='z';c++) { if(a != 'x' && c !='x' && c != 'z' && a !=b && a != c && b != c) { printf("A->%c,B->%c,C->%c",a,b,c); } } } } } int main() { PPmatch(); return 0; } |