题目如下: 题目是转载的 本文是自己刷题的笔记
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX(a,b) (a) > (b) ? (a) : (b)
int highscore(int* nums,int count)
{
if (count == 0)
return 0;
int* dp;
dp = (int*)malloc(sizeof(int) * (count+1));
dp[0] = 0;
dp[1] = nums[0];
for (int k = 2; k <= count; k++)
{
dp[k] = MAX(dp[k-1],nums[k-1] + dp[k-2]);
//第n间不被偷就是 dp[n-1] 假如第n间被偷 那么 n-1间不会被偷 最大时 dp[n]-2加上第n间 第n间储存在num[n-1]内
printf("%d\n",dp[k]);
}
return dp[count];
}
int main()
{
int data[20000];
fgets(data,sizeof(data), stdin);
int nums[1000] = { 0 };
int count = 0;
const char* sep = " ";//分隔符 sep
char* token = strtok(data, sep);
while (token != NULL)
{
nums[count] = atoi(token);//当参数位置传入的为NULL指针时会报错atoi
token = strtok(NULL,sep);
count++;
}
printf("max = %d",highscore(nums,count));
return 0;
}
//
动态规划 dp
1 . 拆分子问题 比如一所学校十个班 怎么知道最高分? 校长分十个班 由每个班最高分得出 然后每个班由老师找
2. 最优子结构 每个班最高分是多少
不是所有问题都是最高子结构 比如 全校最大分差是多少??? 子问题 每个班最大分差 算不出全校
斐波那契数列 递归拆分子问题时重叠计算的问题
动态规划记录重复问题
//
https://renjie.blog.csdn.net/article/details/136537117
跳格子,n个格子 每个各自不同分数 输出最高分数
设动态规划列表dp dp[i]标识前i个房子的最大金额
设有n个房子 则前n间房子最大偷取到dp[n] 前n-1间最多dp[n-1]
加上一间n+1的房子 房子金额为num 那么dp[n+1]有几种情况?
第一 : 偷 n+1 那么 n不能偷 最大为 num+dp[n-1]
第二: 不偷 n 那么 n能偷 最大为dp[n] 为前n个房子金额
细心的我们发现: 难道在前 nnn 间的最高金额 dp[n]dp[n]dp[n] 情况下,第 nnn 间一定被偷了吗?假设没有被偷,那 n + 1n + 1n + 1 间的最大值应该也可能是 dp[n + 1] = dp[n] + numdp[n + 1] = dp[n] + numdp[n + 1] = dp[n] + num 吧?其实这种假设的情况可以被省略,这是因为:
假设第 n 间没有被偷,那么此时 dp[n] = dp[n−1]dp[n] = dp[n - 1]dp[n] = dp[n−1] ,此时 dp[n + 1] = dp[n] + num = dp[n−1] + numdp[n + 1] = dp[n] + num = dp[n - 1] + numdp[n + 1] = dp[n] + num = dp[n−1] + num ,即两种情况可以 合并为一种情况 考虑;
假设第 n 间被偷,那么此时 dp[n + 1] = dp[n] + numdp[n + 1] = dp[n] + numdp[n + 1] = dp[n] + num 不可取 ,因为偷了第 nnn 间就不能偷第 n + 1n + 1n + 1 间。
//
//#define _CRT_SECURE_NO_WARNINGS
fmax和fmin函数 在math.h里面 返回两个浮点数中最大或者最小的一个数
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
//
//#define MAX(a, b) ((a) > (b)) ? (a) : (b)
//
//int highscore(int nums[], int length) {
// if (length == 0) {//长度为0 结束
// return 0;
// }
// int* dp;//创建变长数组dp 动态规划数组
// //int dp[length + 1];
// dp = (int*)malloc((length + 1) * sizeof(int));//给dp申请空间
// for (int k = 0; k <= length; k++) {
// dp[k] = 0;//初始化为 0
// }
// dp[0] = 0;//dp[0] 是凑数的 没用 dp[2] = MAX(dp[1], nums[1] + dp[0])
// //dp1是nums0 dp0 是 0 所以dp[2] 不是 dp1 =nums 0 就是 nums1 + dp0 -->nums1
// //长度为2 时候 最大值不是num0 就是 num1 正确
// //长度为1 直接跳过for 输出 dp1
// dp[1] = nums[0];
// for (int k = 2; k <= length; k++) {
// dp[k] = MAX(dp[k - 1], nums[k - 1] + dp[k - 2]);//递推
// }
// return dp[length];
//}
//
//
//int main() {
// //char input1[200000];
// //fgets(input1, 200000, stdin);
//
// 逗号分隔
// //char* token1 = strtok(input1, " ");
// //int nums1[1000];
// //int count1 = 0;
// //while (token1 != NULL) {
// // nums1[count1++] = atoi(token1);
// // token1 = strtok(NULL, " ");
// //}
// //printf("%d", rob(nums1, count1));
//
// //strtok函数
// //可以用来切割字符串
// // zhangpengwei@biteniuyeke.com
// const char* sep = " ";//分隔符
// //先在串里找,找到一个标记,返回这个标记的指针(标记)
// //strtok会改变字符串 所以一般是临时拷贝的内容 可修改
// //strtok函数中的第一个参数不为null 把第一个标志改为\0
// //strtok函数的第一个参数为null
// //也就是说 找第一个参数时传cp 找后面的传空指针就行了
// //如果找不大到,返回空指针
// char data[200000];
// //int peoNum = 0;
// //scanf("%d", &peoNum);
// //getchar();
// //char* data = NULL;
// //data = (char*)malloc();//这里不能这么弄
// //因为后面要把字符串改编为数字
// //fgets函数原型:char* fgets(char* s, int n, FILE * stream);
// //我们平时可以这么使用:fgets(str, sizeof(str), stdin);
// //其中str为数组首地址,sizeof(str)为数组大小,stdin表示我们从键盘输入数据。
// //fgets函数功能:从文件指针stream中读取字符
// //存到以s为起始地址的空间里,知道读完N - 1个字符,或者读完一行。
// fgets(data, sizeof(data), stdin);
// //C 库函数 char *fgets(char *str, int n, FILE *stream) 从指定的流 stream 读取一行,
// // 并把它存储在 str 所指向的字符串内。
// // 当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
// //str -- 这是指向一个字符数组的指针,该数组存储了要读取的字符串。
// //n -- 这是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度。
// //stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了要从中读取字符的流。
// char* token = strtok(data, sep);
// int score[1000] = { 0 };
// int i = 0;
// while (token != NULL)
// {
// score[i] = atoi(token);
// token = strtok(NULL, sep);
// i++;
// }
// printf("%d\n", highscore(score, i));
// return 0;
//}