纸牌问题,使用贪心可解。
一、纸牌均分
给定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]); }
原创文章,作者:3628473679,如若转载,请注明出处:https://blog.ytso.com/244476.html