1. 程式人生 > 實用技巧 >CF1303D Fill The Bag(貪心)

CF1303D Fill The Bag(貪心)

洛谷評測地址:https://www.luogu.com.cn/problem/CF1303D

解析:

看了幾個題解,應該是有兩種貪心:從大到小或從小到大。

先寫一下從大到小的做法吧。

對a[]進行從小到大的排序。

從大往小遍歷。

很容易想到,儘量把大的往揹包裡放,即a[i]<=n時,直接放進去即可。

如果a[i]>n,這個a[i]拆不拆取決於 i 之前所有物品的大小(sum-a[i])

如果sum-a[i]<n,那麼前面的不夠,所以a[i]要拆,可以先拆一次,然後分到ai和ai+1處,i再從i+1處開始遍歷。

如果sum-a[i]>=n,那麼繼續遍歷即可,ai舍掉。

#include<bits/stdc++.h>
#define
ll long long using namespace std; const int maxn = 1e5 + 95; ll a[maxn]; ll n,m; ll pre[maxn]; int main() { int t; cin>>t; while(t--) { cin>>n>>m; ll sum=0; pre[0]=0; for(int i=1;i<=m;i++) { cin>>a[i]; sum
+=a[i]; pre[i]=pre[i-1]+a[i]; } if(sum<n) { cout<<"-1"<<endl;continue; } int cnt=0; sort(a+1,a+1+m); for(int i=m;i>=1;i--) { if(a[i]<=n) { n-=a[i]; sum
-=a[i]; } else if(sum-a[i]<n) { a[i]/=2; a[i+1]=a[i]; i+=2; cnt++; } else if(sum-a[i]==n) { break; } else { sum-=a[i]; } } cout<<cnt<<endl; } }