Crossing River 題解(貪心)
阿新 • • 發佈:2020-11-22
題目連結
題目大意
t組資料(t<=20)
給你n個人(n<=1000)過河,每個人都有權值,一條船,每次船最多運2個人,每次的花費為兩個人的較大花費
求所有人都過河需要的最小花費
題目思路
經典的過河問題,記錄一下
先將權值從小到大排序一下
每次運兩個人顯然有兩種最優的方法
1:先運(a[1],a[2])過去,a[1]回來,再運(a[n],a[n-1])過去,a[2]回來
cost1=a[n]+2*a[2]+a[1]
2:先運(a[n],a[1])過去,a[1]回來,再運(a[n-1],a[1])過去,a[1]再回來
cost2=a[n]+a[n-1]+2*a[1]
然後當n只有三個的時候特判一下即可
程式碼
#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<vector> #include<string> #include<cstring> #include<iostream> #include<algorithm> //#include<unordered_map> #define fi first #define se second #define debug printf(" I am here\n"); using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; const ll INF=0x3f3f3f3f3f3f3f3f; const int maxn=1000+5,inf=0x3f3f3f3f,mod=1e9+7; const double eps=1e-5; int n,a[maxn]; int main(){ int _;scanf("%d",&_); while(_--){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } sort(a+1,a+1+n); int ans=0; while(n>3){ ans+=min(a[n]+a[n-1]+2*a[1],a[n]+2*a[2]+a[1]); n-=2; } if(n==1){ ans+=a[1]; }else if(n==2){ ans+=a[2]; }else{ ans+=a[1]+a[2]+a[3]; } printf("%d\n",ans); } return 0; }