贪心2--均分纸牌

贪心2--均分纸牌

一、心得

 

二、题目及分析

 

贪心法:

贪⼼算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。

贪心算法不是对所有问题都能得到整体最优解,关键是贪⼼心策略的选择,选择的贪⼼策略必须具备⽆后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。

太概念化了。总结起来三点:

可行性:必须满足问题的约束

局部最优:当前步骤中所有可行的选择里最佳的局部选择。

不可取消:选择一旦做出,后面的步骤就无法改变。

问题要具有贪心选择性:问题的最优解可以通过一系列的局部最优选择来达到。(最重要的一步,决定这个问题是否可以用贪心法来解决,此处的解决特指找到最优解)。

最优子结构性质:指一个问题的最优解一定要包含子问题的最优解。

贪心和DP的差别在哪呢,首先他萌确实都有最优子结构的性质,但是DP通常是以自底向上的方式解决各个子问题(如22中的整装待发问题就是从底部的每一层逐渐建立起那个二维数组),而贪心的方法通常是自顶向上的。

均分纸牌问题的分析:

均分纸牌问题:有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若于张纸牌,然后移动。

  移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。

  现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。

  例如 N=4,4 堆纸牌数分别为:

  ① 9 ② 8 ③ 17 ④ 6

  移动3次可达到目的:

  从 ③ 取 4 张牌放到 ④ (9 8 13 10) -> 从 ③ 取 3 张牌放到 ②(9 11 10 10)-> 从 ② 取 1 张牌放到①(10 10 10 10)。

三、代码及结果

 1 #include <iostream>
 2 using namespace std;
 3 int main(){
 4     int n;
 5     int a[105];
 6     cin>>n;
 7     int sum=0;
 8     for(int i=1;i<=n;i++){
 9         cin>>a[i];
10         sum+=a[i];
11     }
12     int ave=sum/n;
13     for(int i=1;i<=n;i++){
14         a[i]-=ave;
15     }
16     int i=1,j=n;
17     while(!a[i]) i++;
18     while(!a[j]) j--;
19     int step=0;
20     while(i<j){
21         a[i+1]+=a[i];
22         a[i]=0;
23         step++;
24         while(!a[i]) i++;
25     }
26     cout<<step<<endl;
27     return 0;
28 } 

原文地址:https://www.cnblogs.com/Renyi-Fan/p/7130170.html