• leetcode-每日一题-813-最大平均值和的分组(中等,dp)


    这道题我用c写了一百多行代码........实属没想到啊,思路其实是错的,还是想简单了,因为刚开始的思路就是从这numsSize个数里面挑选出最大的k的数进行排序他们的集合然后在这个集合里面进行筛选出序号相同的值最后在进行累加计算就可以得到结果,于是我就写了几个函数用来操作,发现思路错了..................大意了,浪费了一个小时的时间啊,大家想看的可以看看我的代码,我后面看别人的思路解了,动态规划比较简单。

    813. 最大平均值和的分组

    难度中等306收藏分享切换为英文接收动态反馈

    给定数组 nums 和一个整数 k 。我们将给定的数组 nums 分成 最多 k 个相邻的非空子数组 。 分数 由每个子数组内的平均值的总和构成。

    注意我们必须使用 nums 数组中的每一个数进行分组,并且分数不一定需要是整数。

    返回我们所能得到的最大 分数 是多少。答案误差在 10-6 内被视为是正确的。

    示例 1:

    输入: nums = [9,1,2,3,9], k = 3
    输出: 20.00000
    解释: 
    nums 的最优分组是[9], [1, 2, 3], [9]. 得到的分数是 9 + (1 + 2 + 3) / 3 + 9 = 20. 
    我们也可以把 nums 分成[9, 1], [2], [3, 9]. 
    这样的分组得到的分数为 5 + 2 + 6 = 13, 但不是最大值.
    

    示例 2:

    输入: nums = [1,2,3,4,5,6,7], k = 4
    输出: 20.50000
    

    提示:

    • 1 <= nums.length <= 100
    • 1 <= nums[i] <= 104
    • 1 <= k <= nums.length
    1. int cmp(const void* _a, const void* _b)
    2. {
    3. int* a = (int*)_a;
    4. int* b = (int*)_b;
    5. return *a-*b;
    6. }
    7. void fun(int k,int *f,int numsSize,int *nums)
    8. {
    9. int max=0,max_num=0,i,j,flag[numsSize];
    10. memset(flag,0,sizeof(flag));
    11. for(j=0;j
    12. {
    13. max=0;
    14. for(i=0;i
    15. {
    16. if(flag[i]==0)
    17. {
    18. if(max
    19. {
    20. max=nums[i];
    21. max_num=i;
    22. }
    23. }
    24. }
    25. flag[max_num]=1;
    26. f[j]=max_num;
    27. }
    28. }
    29. void fun_begin(int k,int *flag,int f)
    30. {
    31. int i=0;
    32. while(i<=k)
    33. {
    34. flag[i]=f;
    35. i++;
    36. }
    37. }
    38. void fun_end(int k,int *flag,int numsSize,int num)
    39. {
    40. while(k
    41. {
    42. flag[k]=num+100;
    43. k++;
    44. }
    45. }
    46. int min(int x,int y)
    47. {
    48. return x>y?y:x;
    49. }
    50. void fun_mid(int *flag,int numsSize,int *num,int k,int *f)
    51. {
    52. int sign=0,position=0;
    53. fun_begin(f[0],flag,num[f[0]]);
    54. for(int i=0;i-1;i++)
    55. {
    56. sign=min(num[f[i]],num[f[i+1]])+100;
    57. printf("sign=%d\n",sign);
    58. position=f[i]+1;
    59. if(f[i]1])
    60. {
    61. while(position<=f[i+1])
    62. {
    63. flag[position]=sign;
    64. position++;
    65. }
    66. }else{
    67. while(position1])
    68. {
    69. flag[position]=sign;
    70. position++;
    71. }
    72. }
    73. }
    74. fun_end(f[k-1],flag,numsSize,f[k-1]);
    75. }
    76. double calculation(int *flag,int *num,int numsSize,int *f,int k)
    77. {
    78. int i=0,x=num[0],y=1;
    79. double sum=0.0;
    80. for(i=1;i
    81. {
    82. if(flag[i]==flag[i-1])
    83. {
    84. x+=num[i];
    85. y++;
    86. continue;
    87. }
    88. sum+=x/(y*1.0);
    89. printf("\nx=%d y=%d sum=%lf",x,y,sum);
    90. x=num[i],y=1;
    91. }
    92. x=0,y=0;
    93. for(i=f[k-1];i
    94. {
    95. x+=num[i];
    96. y++;
    97. }
    98. sum+=x/(y*1.0);
    99. return sum;
    100. }
    101. double largestSumOfAverages(int* nums, int numsSize, int k){
    102. int f[k],flag[numsSize],num=0;
    103. memset(flag,0,sizeof(flag));
    104. fun(k,f,numsSize,nums);
    105. memset(flag,0,sizeof(flag));
    106. qsort(f,sizeof(f)/sizeof(f[0]),sizeof(f[0]),cmp);
    107. fun_mid(flag,numsSize,nums,k,f);
    108. for(int i=0;i
    109. {
    110. printf("%d ",f[i]);
    111. }
    112. printf("\n");
    113. for(int j=0;j
    114. {
    115. printf("%d ",flag[j]);
    116. }
    117. return calculation(flag,nums,numsSize,f,k);
    118. }

    最后的结果肯定是错误的,懒得改了,随便写了

    dp去求解主要看思路:

    1.当前状态,先给i和j等于0进行初始化,然后判断当前状态属于哪一种状态即可,套入状态转移方程即可求解

    2.状态转移方程,从上一个节点开始进行循环,由于我们的列祖是分组的,所以我们需要去上一层进行开始排查,然后每回合取最大值即可,到了最后整合其最大值就可以得到结果

    确实是一个好方法

  • 相关阅读:
    使用Scipy优化梯度下降问题
    [1]-基于图搜索的路径规划基础
    微信小程序-request fail
    rmq发送消息-服务端
    初识SPDK,从SPDK的软件架构到使用实操
    在Go项目中使用ELK进行日志采集
    linux内核网络源码-用户空间与内核的接口
    《MySQL实战45讲》——学习笔记12 “InnoDB刷脏页的控制策略“
    智能运维|AIRIOT智慧光伏管理解决方案
    FAlphaBlend——Unreal中的插值助手
  • 原文地址:https://blog.csdn.net/qq_59002046/article/details/128086825