• 用动态规划算法均分纸牌


    有n堆卡片,每堆卡片的张数不同,总的张数不一定是n的倍数。在任意两堆卡片之间,移动任意张卡片,最终目标是让最多一堆的卡片张数与最少一堆的卡片张数的差小于等于1。规定将第i堆上的一张卡片移动到第j堆上,或者相反移动,代价均为|i-j|。例如,当n=5,每堆张数分别是5,9,2,12,9时,最小移动代价是8。

    请问
    1.如何理解A、B行的状态转移方程的含义
    2.题目中从第i堆移动一张卡片到第j堆上,或者相反移动,代价均为|i-j|,在程序中是如何计算的

    
    部分代码如下:
    const int M=10;
    long dp[M][M],card[M],s[M];
    int main(){
        int n,i,j;
        cin>>n;
        for (i=1;i<=n;i++){
            cin>>card[i];
            s[i]=s[i-1]+card[i];
        }
        int r=s[n]%n,q=s[n]/n;
        for(i=1;i<=n;++i){ 
            for(j=0;j<=r;++j){ 
                int c=abs(s[i]-q*i-j);
                dp[i][j]=dp[i-1][j]+c;//A
                if(j)
                    dp[i][j]=min(dp[i-1][j-1]+c,dp[i][j]);//B
            }
        }
        cout<[n][r]<
    • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-27 18:03
      关注

      引自免费微信小程序:皆我百晓生

      这个问题是一个典型的动态规划问题,我们需要找到移动卡片的最佳策略使得最多一堆和最少一堆的卡片数之差最小。下面我会对代码中的关键部分进行解释。

      问题解答

      1. 如何理解A、B行的状态转移方程的含义?

      在动态规划中,状态转移方程是关键,它描述了从子问题到整个问题的解决方案的过渡。在这个问题中:

      • dp[i][j] 表示当前已经处理了前 i 堆卡片,其中第 i 堆卡片数量为 j 的情况下的最小代价。这里的 j 是一个范围,表示从 0 到当前第 i 堆卡片的总数之间的任何数。我们的目标是找到 dp[n][r],其中 n 是总堆数,r 是所有卡片数量对 n 取模的结果。这样我们就能知道为了达到目标状态所需要的最小代价。

      A行的状态转移方程 dp[i][j]=dp[i-1][j]+c 表示:保持第 i 堆卡片的数量不变(即不移动任何卡片),代价为 c(当前堆卡片数与平均值的差的绝对值)。这是一种可能的解决方案,虽然它可能不是最优的,但我们需要考虑所有可能的解决方案。

      B行的状态转移方程 dp[i][j]=min(dp[i-1][j-1]+c, dp[i][j]) 在考虑了移动卡片的情况。如果从第 i-1 堆移动一张卡片到第 i 堆(使得第 i 堆卡片数量变为 j),代价为 c,那么新的状态转移代价就是 dp[i-1][j-1]+c。这是另一种可能的解决方案,我们需要在这两种方案中选择一个最优的。所以 B 行是对 A 行的优化,考虑了移动卡片的可能性。

      2. 在程序中是如何计算移动代价的?

      移动代价的计算是基于题目描述的:“从第 i 堆移动一张卡片到第 j 堆上,或者相反移动,代价均为 |i-j|”。在代码中,这个代价被计算为 c = abs(s[i]-q*i-j),其中 s[i] 是前 i 堆卡片的总数,q*i 是平均分配后的数量(总数量除以堆数),而 j 是当前考虑的特定堆的卡片数量。代价 c 就是当前堆与平均值的差的绝对值。这个代价反映了我们需要移动多少卡片来达到平均分配的目标。在动态规划的过程中,我们会考虑所有可能的移动和它们的代价,然后选择最优解。

      总结

      动态规划的关键在于理解和建立状态转移方程,以及正确地计算每一步的代价。在这个问题中,我们通过迭代每一堆卡片,考虑是否移动卡片以及移动到哪里,来计算最小代价。通过这种方式,我们最终能够得到让最多一堆和最少一堆的卡片数之差最小的策略。

    • 相关阅读:
      【毕业设计】基于STM32的空气质量检测仪 - 环境检测盒子 - 单片机 物联网
      Jupyter Notebook 换个主题清爽了很多
      有序列表 – ol – li
      如何使用ffmpeg转换图片格式
      第2-3-7章 个人网盘服务接口开发-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss
      Bootstrap页面整合(十二)
      TypeScript中的类型断言
      N-128基于springboot,vue酒店管理系统
      django梳理
      【ChatGPT】【Gemini】-用Python调用google的Gemini API
    • 原文地址:https://ask.csdn.net/questions/8124764