2018 ACM-ICPC 亞洲區域賽青島站 J-Books(貪心)
阿新 • • 發佈:2018-12-03
思路來源
https://blog.csdn.net/Game_Acm/article/details/83745455
題意
有n本書從第1本書開始買,對於每本書能買則買,求恰好買m本書的最大攜帶錢數,
如果攜帶錢數無上限(即存在INF的情況能買下所有書)輸出Richman,
如果不存在購買m本書的情況(即存在為0的書的數量大於m)輸出Impossible
題解
要是m==n就是Richman,要買下所有書顯然錢無限。
先把價格為0的書全部撈到,記為cnt,cnt若超過m就是Impossible。
由於最終的答案是錢數的最大,從前往後遇到一本書,
若這本書比後面的貴,選這本顯然更優。
若這本書比後面的便宜,最優錢數下,這本書也買得起。
而遇到一本能買的書就不得不買,
所以無論如何花的錢數,都是前(m-cnt)本書的價錢。
此外,可以攜帶後面的書裡最便宜的那本減一的錢數,以保證什麼也買不了。
程式碼
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cmath> #include <set> #include <map> #include <vector> #include <stack> #include <queue> #include <functional> const int INF=0x3f3f3f3f; const int maxn=1e5+10; const int mod=1e9+7; const int MOD=998244353; const double eps=1e-7; typedef long long ll; #define vi vector<int> #define si set<int> #define pii pair<int,int> #define pi acos(-1.0) #define pb push_back #define mp make_pair #define lowbit(x) (x&(-x)) #define sci(x) scanf("%d",&(x)) #define scll(x) scanf("%lld",&(x)) #define sclf(x) scanf("%lf",&(x)) #define pri(x) printf("%d",(x)) #define rep(i,j,k) for(int i=j;i<=k;++i) #define per(i,j,k) for(int i=j;i>=k;--i) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; int t,n,m,cnt; ll ans,miin,a[100005],q[100005]; int main() { sci(t); while(t--) { ans=0,cnt=0; miin=999999999999; sci(n),sci(m); rep(i,0,n-1) { scll(a[i]); if(!i)q[i]=a[i]; else q[i]=q[i-1]+a[i]; if(a[i]==0)m--; } if(m<0)puts("Impossible"); else { rep(i,0,n-1) { if(!a[i])continue; if(cnt++<m)ans+=a[i]; else miin=min(miin,a[i]); } if(ans==q[n-1])puts("Richman"); else printf("%lld\n",miin-1+ans); } } return 0; }