P1223 排队接水
题目传送门
这是一道很入门的贪心例题,正如我前面所说,我们根据样例就可以很快地发现,答案符合将接水时间从小到大排序这一特点。那么,自然联想,这就是正解。
证明:假设有
\[a_1<a_2<a_3...<a_n
\]
那么
\[t=(n-1)a_1+(n-2)a_2+...a_{n-1}
\]
假设将\(a_1\)与\(a_2\)的位置交换,
\[t'=(n-1)a_2+(n-2)a_1+...+a_{n-1}
\]
\[t-t'=(n-1)(a_1-a_2)+(n-2)(a_2-a_1)=(n-1)(a_1-a_2)-(n-2)(a_1-a_2)=a_1-a_2<0
\]
\[\therefore t<t'
\]
同理,可以证得,对于原序列的顺序交换任意几个数组位置,得出的时间都会比原时间大,即将初始序列升序排序即可。
代码如下:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1000+5;
int n;
struct node{
int i;
int num;
}a[N];
bool cmp(node x,node y){
return x.num<y.num;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].num;
a[i].i=i;
}
sort(a+1,a+n+1,cmp);
double t=0;
for(int i=1;i<=n;i++){
t+=a[i].num*(n-i);
}
t/=n;
for(int i=1;i<=n;i++)cout<<a[i].i<<' ';
cout<<endl<<fixed<<setprecision(2)<<t<<endl;
return 0;
}