下面程序的输出为( )。
#include <iostream>
using namespace std;
int a[10][10];
int main() {
int m = 5, n = 4;
for (int x = 0; x <= m; x++)
a[x][0] = 1;
for (int y = 1; y <= n; y++)
a[0][y] = 1;
for (int x = 1; x <= m; x++)
for (int y = 1; y <= n; y++)
a[x][y] = a[x - 1][y] + a[x][y - 1];
cout << a[m][n] << endl;
return 0;
}模拟程序执行过程,逐行跟踪变量变化,特别关注循环边界和递归终止条件。
模拟执行时注意:① 循环变量的起始和终止值;② 递归的边界条件;③ 数据类型转换和精度问题。
【考点】动态规划|组合计数|递推关系
考纲定位 本题是 GESP 八级"动态规划"模块的代表性真题。命题人把"路径计数"这类组合问题包装成数组递推,卡住的是考生"看到代码就写公式"的惯性——不会先读懂递推式,直接套用阶乘或简单加法,导致选错。
解题思维 代码先初始化第一行和第一列为 1,再按 a[x][y]=a[x-1][y]+a[x][y-1] 填充。这就是经典的"网格路径数"递推:到达 (x,y) 只能从上方或左方来,所以路径数等于两者之和。最终 a[m][n] 即 C(m+n-2,m-1),代入 m=5,n=4 得 C(9,4)=126。
陷阱拆解 错项全是"直觉陷阱":A、B 是只盯着循环边界(以为答案是 4 或 5),D 是误以为答案等于阶乘乘积(m!·n!)。最阴险的细节是"第一行/列全 1"的边界条件——如果忽略它,递推就会从 0 开始,整个数组全 0,却没人会选"0"。这题就是考"先读懂代码,再列公式"。
反命题思维 命题人若把循环改成 x≤m-1、y≤n-1,答案就会变成 a[m-1][n-1] = C(8,3)=56;若把初始化改成 a[x][0]=x+1、a[0][y]=y+1,就变成了"带权路径数",答案会完全不同。刷到类似题,先自问"这题到底要递推什么?边界值是什么?"——这才是破题关键。