算法学习之—— 贪心算法

概念:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解

算法特征:选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

样例

1.翻硬币问题(https://www.dotcpp.com/oj/problem1453.html):不必太过细致考虑,题目中所说最少次数其实就是依照最基本的规则,对每个硬币进行依次判断,当第i个位置的字符与模板串不相同时,对此位以及第i+1位进行取反。代码如下(错误率50%)

错误代码:

#include <iostream>
#include <string>
using namespace std;
int main ()
{
  string s1,s2;
  cin>>s1;
  cin>>s2;
  int len = s1.length();
  char a[100]={0};
  s1.copy(a,len,0);
  char b[100]={0};
  s2.copy(b,len,0);
  int sum=0;
  for(int i=0;i<len;i++)

  {
      if(a[i]==b[i])

        continue;
  cout<<i<<" ";
          sum++;
          b[i]=a[i];
          if(b[i+1]=='*')
            b[i+1]='o';
          if(b[i+1]=='o')
            b[i+1]='*';

  }
  cout<<endl<<a<<endl<<b;
 cout<<sum<<endl;
    return 0;
}
错误原因:没有认真读题,题目中前一个是初始状态串,后一个是目标串,上面错误的代码是将b串进行更改,所以测试输出时两个串完全一样,但得到的总次数sum、却不同!!!

反思:认真读题!!!

翻硬币正确代码:

#include <iostream>
#include <string>
using namespace std;
int main ()
{
   string s1,s2;
   cin>>s1>>s2;
   char a[1000],b[1000];
   int len=s1.length();
   s1.copy(a,len,0);
   s2.copy(b,len,0);
   int sum=0;
   for(int i=0;i<len-1;i++)
   {
       if(a[i]==b[i])
        continue;
       else
       {
           sum++;
           a[i]=b[i];
           if(a[i+1]=='*')
            a[i+1]='o';
           else
            a[i+1]='*';
       }

   }
   cout<<sum;
    return 0;
}

 

2.打水问题(https://www.dotcpp.com/oj/problem1523.html):从小到大顺序排列后,采用依次分队的方法,这样可保证总时间最短。在代码实现过程中,注意对数组进行间隔固定个数取数的算法。

#include <iostream>
#include <string>
using namespace std;
int main ()
{
   int N,M;
   cin>>N>>M;
   int peo[1000];
   int t;
   for(int i=0;i<N;i++)
    cin>>peo[i];
    for(int i=0;i<N;i++)
    {
        for(int j=i;j<N;j++)
        {
            if(peo[i]>peo[j])
            {
                t=peo[i];
                peo[i]=peo[j];
                peo[j]=t;
            }
        }
    }
    long long  sum=0;
    int l=0;
    for(int i=0;i<M;i++)
    {
        l=0;
        for(int j=i;j<N;)
        {
            l=peo[j]+l;
            sum=sum+l;
            j=j+M;
        }
        sum=sum-l;
    }
    cout<<sum;
    return 0;
}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐乐_16

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值