分析:
この質問は貪欲なアルゴリズムを使用しています。
個人的なアイデア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