均分纸牌的最小移动步数

纸牌问题,使用贪心可解。

一、纸牌均分

  给定n堆纸牌,每堆纸牌有若干张,现要使着n堆纸牌平均分配,即每堆张数相等。每次移动可以使一堆牌向其左边的一堆或右边的一堆移动若干张牌。求最少移动次数。

  这个题目相对简单,求出平均数,一一填平数组,其实不为零的数量就是结果了。

{
    //t是纸牌总数
    int ans = 0;
    for (int i = 1;i <= n;i ++)
        b[i] = a[i] - t / n;
    for (int i = 1;i <= n;i ++)
    {
         if (b[i] != 0) ans ++;
         b[i + 1] += b[i];
    }      
}

二、每次只能移动一张牌的纸牌均分

  和上道题差不多,只不过这回一次只能移动1张牌,每移动一次都要计入最后的移动步数。

  同样使用贪心算法,只是计算最后的结果每次都是加上需要移动到下一次的纸牌数(可正可负)。

{
    for (int i = 1;i <= n;i ++)
        b[i] = a[i] - t / n;
    for (int i = 1;i <= n;i ++)
    {
         sum[i] = sum[i - 1] + b[i];
         ans += abs(sum[i]);    
    }      
}

三、每次只能移动一张牌的环状纸牌均分

  头尾直接可以交换数据,看代码。

{
    for (int i = 1;i <= n;i ++)
        b[i] = a[i] - t / n;
    for (int i = 1;i <= n;i ++)
        sum[i] = sum[i - 1] + b[i];
    sort(sum + 1,sum + n + 1);
    int ans = 0;
    for (int i = 1;i <= n;i ++)
        ans += abs(sum[i] - sum[(1 + n) / 2]);
}

 

posted @ 2022-04-16 17:54  Mysterioushh  阅读(104)  评论(0编辑  收藏  举报