1. 程式人生 > >5937. 斬殺計劃

5937. 斬殺計劃

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