1229バッテリー寿命のソリューション

ここに画像の説明を挿入

分析:
この質問は貪欲なアルゴリズムを使用しています。

個人的なアイデア1(これは、タイムアウトを渡すことができないという単なるアイデアです):
配列を使用して、各バッテリーの寿命を記録します。
最初に考えたのは、寿命の最大値と2番目に大きい値を毎回見つけることでした。(毎回ソートできますが、時間の複雑さが非常に高くなります)毎回、最大値と次に大きい値が0.5ずつ減算されます。(0.5は各バッテリーの係数であるため)次に見つかった最大値が0になるまで。-目的は、可能な限り多くのバッテリーを維持することです。そのため、使用するたびに、余命の長いバッテリーを使用します。

アイデア2:
方法を変えて、結果から始めます。
すべてのバッテリーの寿命と合計を見つけます。
sum(and)-max(最大値)<= maxの場合、それは他のバッテリーが消費されており、maxの寿命を相殺できない(または単に)ことができないことを意味し、結果は小さいバッテリー寿命の合計sum-maxの制限になります。
sum(max)-max(最大値)> maxの場合、nの値は> = 3でなければならないことを意味します(この場合は3つ以上しか発生しません)。この場合、バッテリーは途中で交換できます。 、したがって、各バッテリーは整数であり、0.5時間の倍数であってもかまいません。これらの偶数の場合、すべてのバッテリーが消耗するように調整する必要があります(毎回2つの異なるバッテリーの0.5が消費されていると見なすことができます)。したがって、結果はsum / 2になります。

コード:
アイデア1(タイムアウトコードは終了できません)

#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;

//思路:公约数 半个小时。 
//尽量选取两个较大的数的半个小时,保证有更多的没有用完的电池 

double r[1001];
double a[1001]; 
int m_sort(int s,int t)//归并排序
{
 if(s==t)
  return 0;
 int mid=(s+t)/2;
 m_sort(s,mid);
 m_sort(mid+1,t);
 
 int i=s,j=mid+1,k=s;
 while(i<=mid&&j<=t)
 {
  if(a[i]<=a[j])
  {
   r[k]=a[i];
   k++;
   i++;
  }
  else
  {
   r[k]=a[j];
   k++;
   j++;
  }
  
 }
 while(i<=mid)
 {
  r[k]=a[i];
  k++;
  i++;
 }
 while(j<=t)
 {
  r[k]=a[j];
  k++;
  j++;
 }
 
 for(int i=s;i<=t;i++)
  a[i]=r[i];
}


int main()
{
 int n;
 int nm=0;//记录可以用几个半个小时 
 int max_z,max_ci; 
 while(scanf("%d",&n)!=EOF)
 {
  nm=0; 
  for(int i=1;i<=n;i++)
  {
   cin>>a[i];
  }
  a[0]=0;
  m_sort(1,n);//排序 
  max_z=n;
  max_ci=n-1;//每次找最大和次大的两个值 
  while(a[max_ci]!=0)//直到第二大的那个为0 ,就剩1节电池或者没有电池了为止 
  {
   nm++;
   a[max_z]=a[max_z]-0.5;
   a[max_ci]=a[max_ci]-0.5;
   max_z=max_ci=0;//每次的初始化 
   for(int i=1;i<=n;i++)//先找最大值 
   {
    if(a[i]>a[max_z])
     max_z=i;
   }
   for(int i=1;i<=n;i++)//再找次大值 
   {
    if(a[i]>a[max_ci]&&max_z!=i)
     max_ci=i; 
   }
  }
  printf("%.1f\n",(float)nm/2);
 }
 return 0;
 } 

コード2:合格できます

#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
//思路:
//求一下sum总和,如果sum减去最大值小于最大值max就说明没有什么组合可以更大的抵消最大值,结果就是其他值轮番消耗最大值,小电池的和的极限,即sum-max。 
//第二种情况是sum减去最大值大于了大值,这种情况的结果是sum的一半。因为这样n一定会>=3,当>=3时就可以出现换电池的情况,因为每一个电池都是0.5的偶数倍,所以一定可以协调全部用完 
double r[1001];
double a[1001]; 
int m_sort(int s,int t)//归并排个序 
{
 if(s==t)
  return 0;
 int mid=(s+t)/2;
 m_sort(s,mid);
 m_sort(mid+1,t);
 
 int i=s,j=mid+1,k=s;
 while(i<=mid&&j<=t)
 {
  if(a[i]<=a[j])
  {
   r[k]=a[i];
   k++;
   i++;
  }
  else
  {
   r[k]=a[j];
   k++;
   j++;
  }
  
 }
 while(i<=mid)
 {
  r[k]=a[i];
  k++;
  i++;
 }
 while(j<=t)
 {
  r[k]=a[j];
  k++;
  j++;
 }
 
 for(int i=s;i<=t;i++)
  a[i]=r[i];
}


int main()
{
 int n;
 double sum=0;
 while(cin>>n)
 {
  sum=0;
  for(int i=1;i<=n;i++)
  {
   cin>>a[i];
   sum+=a[i];//求和 
  }
 // cout<<sum<<endl;
  m_sort(1,n);//排一下序
  double max_s=a[n];//求出最大值 
  if(sum-max_s<=max_s)//第一种 
   printf("%.1lf\n",sum-max_s);
  else if(sum-max_s>max_s)//第二种 
   printf("%.1lf\n",sum/2);
  
 }
 
 return 0;
}

————————————————
著作権ステートメント:この記事は、CSDNブロガー「Listen to the Bamboo Wind」のオリジナル記事であり、CC 4.0 BY-SA著作権契約に従います。元のソースリンクを添付して転載してくださいこのステートメント。
元のリンク:https://blog.csdn.net/qq_40575034/article/details/103338672

公開された33元の記事 ウォンの賞賛0 ビュー167

おすすめ

転載: blog.csdn.net/weixin_42790071/article/details/105430215