找朋友 c语言代码实现

 题目如下: 题目是转载的 本文是自己刷题的笔记


#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;
//}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值