2019年3月16日:贪心复习;动态规划预习

首先,来复习一下贪心,对一个问题的每个过程求局部最优解,从而最后推导出全局最优解。
上例题。

有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。
移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。
现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。
对这个题目,首先应该想到怎么移动纸牌。我们可以从移动纸牌的张数入手。
由当前纸牌数减去平均数,就可以得到要移动的纸牌数,正数是多了几张,负数是少几张。最终目的是使所有数都变成0.

       cin>>n;
  ave=0;step=0; 
  for (i=1;i<=n;++i)
   {
    cin>>a[i]; 
    ave+=a[i];              //读入各堆牌张数,求总张数ave
   } 
  ave/=n;                                          //求牌的平均张数ave
  for (i=1;i<=n;++i) a[i]-=ave;         //每堆牌的张数减去平均数
  i=1;j=n;
  while (a[i]==0&&i<n) ++i;            //过滤左边的0
  while (a[j]==0&&j>1) --j;              //过滤右边的0
  while (i<j)
   {
   a[i+1]+=a[i];                              //将第i堆牌移到第i+1堆中去
   a[i]=0;                                        //第i堆牌移走后变为0
   ++step;                                      //移牌步数计数 
   ++i;                                            //对下一堆牌进行循环操作
   while (a[i]==0&&i<j) ++i;          //过滤移牌过程中产生的0
   } 
  cout<<step<<endl; 

在这之中有一个弯,就是如果一个数是1,-6,而第二个数是1,-5,都欠着牌,而且后面的不够补到前面的,怎么办。
其实照样补过去,第二个变成-11,-11。由后面多的总会补回来。

动态规划预习
动态规划,也是一种最优解的算法。他将问题实例分解为更小的/相似的子问题,并存储子问题的解,使得每个子问题只求解一次,最终获得原问题的答案。
他与贪心法类似,都是将问题实例归纳为更小的、相似的子问题,并通过求解子问题产生一个全局最优解,但动态规划通过求解局部子问题的最优解来达到全局最优解。
如要求一个问题的最优解,而且该问题能够分解成若干个子问题,并且小问题之间也存在重叠的子问题,则考虑采用动态规划。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值