1. 程式人生 > 實用技巧 >Function (思維+優先佇列)

Function (思維+優先佇列)

Function

解題思路:

因為 x 是正整數,所以每個 Fi 都必須先分配 xi=1。這時候還剩下 m-n 個 1 沒有分配,採用貪心原則。首先需要先知道對於每一次分配的1,產生的增量為:

所以我們每次都取最小的增量,最後即為最小的增量。這就用到了優先佇列

AC_Code:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <cmath>
 7
typedef long long ll; 8 using namespace std; 9 const int maxn = 1e5+5; 10 11 ll n,m,a[maxn],b[maxn],c[maxn]; 12 struct node{ 13 ll id,val; 14 bool operator < (const node &r) const{ 15 return r.val<val; 16 } 17 }tmp; 18 priority_queue<node>que; 19 ll x[maxn]; 20 21
int main() 22 { 23 while( ~scanf("%lld%lld",&n,&m)){ 24 while( !que.empty() ) que.pop(); 25 ll ans=0; 26 for(int i=1;i<=n;i++){ 27 scanf("%lld%lld%lld",&a[i],&b[i],&c[i]); 28 tmp.id = i; 29 tmp.val = 2ll*a[i]*1ll+a[i]+b[i];
30 x[i] = 1; 31 que.push(tmp); 32 ans += a[i]+b[i]+c[i]; 33 } 34 ll num = m-n; 35 while( num ){ 36 num--; 37 int id = que.top().id; 38 x[id]++; 39 ans += que.top().val; 40 tmp.id = id; 41 tmp.val = 2*a[id]*x[id]+a[id]+b[id]; 42 que.pop(); 43 que.push(tmp); 44 } 45 printf("%lld\n",ans); 46 } 47 return 0; 48 }