Description

        众所周知,小J和小G是死对头,一天小G带领一群小弟找到了小J。
问题描述
        小G有n个小弟,第i个小弟有ai点攻击力,小G有m点血量。
        小J在小G找小第的时间里去找小Z学到了膜法,他在大战前配置了三种魔法药水
        1:复用型药水:花费1法力值,选择小G的攻击力小于等于2的一个小弟让他跟随自己(变为自己的小弟并且攻击力和属于小G时一样)
        2:猎人药水:花费4法力值,选择小G的攻击力小于等于3的一个小弟让他跟随自己
        3:腐败药水:花费1法力值,使小G所有小弟攻击力降低三点(使用前两种魔法将小弟拉到自己阵营时小弟攻击力就是当前的攻击力,即小J的小弟攻击力只能为1,2,3)
        为了向小G展现自己的力量,他打算在召集到一些小弟后发动攻击(每个小弟打一次)直接秒杀小G(攻击力大于等于m)
        由于智商有限,小J在配置腐败药水时会花费很大精力,他需要知道自己最少使用多少腐败药水,并在腐败药水数量最小的情况下花费最小的法力值
 

Input

第一行两个正整数n,m表示小G的小弟数量和血量
第二行n个正整数表示小G所有小弟的攻击力

Output

        一行两个整数表示最小的腐败药水数量和在腐败药水最小的情况下法力值花费,如果无论如何都无法战胜,输出一个整数-1
 

Sample Input

Sample Input1:
3 5
1 2 3

Sample Input2:
8 8
10 20 30 40 50 60 70 80

Sample Input3:
8 80
10 20 30 40 50 60 70 80

Sample Output

Sample Output1:
0 5

样例说明
        对2,3小弟使用复用型药水和猎人药水

Sample Output2:
16 23

样例说明
使用16个腐败药水
在第3个腐败药水时拉10,攻击力为1
在第6个腐败药水时拉20,攻击力为2
在第9个腐败药水时拉30,攻击力为3
在第16个腐败药水时拉50,攻击力为2

Sample Output3:
-1
 做法:贪心,显然2>1>3
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #define N 5000007
 6 using namespace std;
 7 int n,m;
 8 int a[N],list[N],tot;
 9 
10 inline int read(){
11     int s=0;
12     char ch=getchar();
13     for(;ch<'0'||ch>'9';ch=getchar());
14     for(;ch>='0'&&ch<='9';s=s*10+ch-'0',ch=getchar());
15     return s;
16 }
17 
18 int main(){
19     freopen("zhanshajihua.in","r",stdin);
20     freopen("zhanshajihua.out","w",stdout);
21     n=read();
22     m=read();
23     for(register int i=1;i<=n;++i) a[i]=read();
24     sort(1+a,1+a+n);
25     if (m==0){
26         printf("0 0");
27         return 0;
28     }
29     register int sum=0,ans=0,attack=0;
30     for(register int i=1;i<=n;){
31         while(a[i]-sum*3>0) ++sum;
32         --sum;
33         int j=i;
34         while(j<=n){
35             if (a[j]-sum*3>3) break;
36             while(a[j]-sum*3==0&&j<=n) j++;
37             if (a[j]-sum*3<3) ++ans,attack+=a[j]-sum*3,list[++tot]=a[j]-sum*3;
38             else ans+=4,attack+=3,list[++tot]=3;
39             ++j;
40         }
41         if (attack>=m) break;
42         i=j; 
43     }
44     ans+=sum;
45     sort(list+1,list+tot+1);
46     while(tot&&list[tot]==3){
47         if (attack-list[tot]>=m){
48             if (list[tot]==3)    attack-=3,ans-=4;
49             else attack-=list[tot],--ans;
50         }
51         if (attack==m) break;
52         tot--;
53     }
54     int j=1;
55     while(j<=tot){
56         if (attack-list[j]>=m){
57             if (list[j]==3)    attack-=3,ans-=4;
58             else attack-=list[j],--ans;
59         }
60         if (attack==m) break;
61         j++;
62     }
63     if (attack>=m) printf("%d %d",sum,ans);
64     else printf("-1");
65 }
View Code