原题链接:A+B+C+D
解题思路:
看到这道题第一反应就是深度优先搜索,提交后超时
void dfs(int target, int pos, int *cnt) {
if (pos == 3) {
(*cnt)++;
return;
}
for (int i = 1; i < target; i++) {
dfs(target - i, pos + 1, cnt);
}
}可以发现这是一道典型的动态规划算法题,
| 0 | 1 | 2 | 3 | 4 | 5 | |
| 0(A) | 0 | 1 | 1 | 1 | 1 | 1 |
| 1(B) | 0 | 0 | 1 | 2 | 3 | 4 |
| 2(C) | 0 | 0 | 0 | 1 | 3 | 6 |
| 3(D) | 0 | 0 | 0 | 0 | 1 | 4 |
通过观察不难发现动态规划方程为:
dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1]
dp[i][j]在这里的含义为,i + 1个数进行组合使得组合后的数字之和为j,这个时候共有dp[i][j]中组合方式。
注意事项:
参考代码:
#include <stdio.h>
#define max(a, b) (((a) > (b)) ? (a) : (b))
int main() {
int t;
scanf("%d", &t);
int arr[t]; // 输入数组
int max = 0; // 取到输入数组中最大值,方便确定dp动归数组的的大小
for (int i = 0; i < t; i++) {
scanf("%d", &arr[i]);
max = max(arr[i], max);
}
int dp[4][max + 1];
for (int i = 0; i <= max; i++) {
dp[0][i] = 1; // 第一行都是1
}
for (int i = 0; i < 4; i++) {
dp[i][0] = 0; // 第一列都是0
}
for (int i = 1; i < 4; i++) {
for (int j = 1; j <= max; j++) {
dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1]; // 动态规划方程
}
}
for (int i = 0; i < t; i++) {
printf("%d\n", dp[3][arr[i]]); // 第i个输入数据进行A+B+C+D时的排列组合
}
return 0;
}0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复