• G. Good Key, Bad Key(暴力)


    Problem - 1703G - Codeforces

    有n个箱子。第i个箱子里有ai个硬币。你需要按顺序打开所有n个箱子,从箱子1到箱子n。

    你可以用两种类型的钥匙来打开箱子。

    一把好钥匙,使用它需要花费k个硬币。
    坏钥匙,不需要花费任何金币,但会将每个未打开的箱子里的所有金币减半,包括它要打开的箱子。减半的操作将使每个被减半的箱子减至最接近的整数。换句话说,用一把坏钥匙打开i号箱子会做ai=⌊ai2⌋,ai+1=⌊ai+12⌋,...,an=⌊an2⌋。
    任何钥匙(包括好的和坏的)在使用后都会断掉,也就是说,它是一次性的使用。
    你总共需要使用n把钥匙,每个箱子一把。最初,你没有金币,也没有钥匙。如果你想使用一把好钥匙,那么你需要购买它。

    在这个过程中,你可以负债;例如,如果你有1个硬币,你可以购买一把价值k=3个硬币的好钥匙,你的余额将变成-2个硬币。

    请找出从1号箱子到n号箱子的顺序打开所有n个箱子后,你能拥有的最大数量的硬币。

    输入
    第一行包含一个整数t(1≤t≤104)--测试案例的数量。

    每个测试案例的第一行包含两个整数n和k(1≤n≤105;0≤k≤109)--分别为箱子的数量和一把好钥匙的成本。

    每个测试案例的第二行包含n个整数ai(0≤ai≤109)--每个箱子里的硬币数量。

    所有测试案例的n之和不超过105。

    输出
    对于每个测试案例,输出一个单一的整数--按照从箱子1到箱子n的顺序打开箱子后所能获得的最大硬币数。

    请注意,有些测试案例的答案不适合32位整数类型,所以你应该在你的编程语言中至少使用64位整数类型(如C++的long long)。

    例子
    inputCopy
    5
    4 5
    10 10 3 1
    1 2
    1
    3 12
    10 10 29
    12 51
    5 74 89 45 18 69 67 67 11 96 23 59
    2 57
    85 60
    输出拷贝
    11
    0
    13
    60
    58
    备注
    在第一个测试案例中,一个可能的策略是如下的。

    用5个金币购买一把好钥匙,然后打开1号箱子,得到10个金币。你目前的余额是0+10-5=5个硬币。
    用5个硬币买一把好钥匙,然后打开箱子2,得到10个硬币。你目前的余额是5+10-5=10个硬币。
    用一把坏钥匙打开3号箱子,由于使用了坏钥匙,3号箱子的硬币数变成⌊32⌋=1,4号箱子的硬币数变成⌊12⌋=0,你现在的余额是10+1=11。
    使用一把坏钥匙,打开4号箱子。由于使用了一把坏钥匙,4号箱子里的硬币数量变成了⌊02⌋=0,你现在的余额是11+0=11。
    在这个过程结束时,你有11个硬币,这可以证明是最大的。

    题解:

    根据每次用坏钥匙,当前位及后面所有宝箱金币数均减半(代表后面不会再用好钥匙了,因为除了2,比起以前再用好钥匙会更小)

    再结合数据范围1e9,顶多32次后,i + 32后的宝箱就全为0了

    那么我们直接暴力枚举再0~n位,每个i后顶多32次就结束了,是可行的

     

    1. #include<iostream>
    2. #include<algorithm>
    3. #include<cstring>
    4. #include<string>
    5. #include<map>
    6. #include<vector>
    7. #include<queue>
    8. using namespace std;
    9. #define int long long
    10. //1 1 3 3 3
    11. int a[300050];
    12. int s[300050];
    13. int b[300050];
    14. void solve()
    15. {
    16. int n,k;
    17. cin >> n >> k;
    18. for(int i = 1;i <= n;i++)
    19. cin >> a[i];
    20. int s = 0;
    21. int ans = 0;
    22. for(int i = 0;i < n;i++)
    23. {
    24. int ss = s;
    25. for(int j = i+1;j <= min(n,i+32);j++)
    26. {
    27. int cnt = a[j];
    28. cnt >>=j - i;
    29. ss += cnt;
    30. }
    31. ans = max(ss,ans);
    32. s += a[i+1] - k;
    33. }
    34. ans = max(ans,s);
    35. cout<<ans<<"\n";
    36. }
    37. signed main()
    38. {
    39. int t = 1;
    40. cin >> t;
    41. while(t--)
    42. {
    43. solve();
    44. }
    45. }
    46. //2 5
    47. //3
    48. //9 7
    49. //2 3 4 3

  • 相关阅读:
    Springboot门诊电子处方管理系统3kqta计算机毕业设计-课程设计-期末作业-毕设程序代做
    【java零基础入门到就业】第四天:Notepad++软件的下载和安装
    稳压电源: 电路图及类型
    电气滑环更换原因分析
    Javascript中setTimeout设置为0的意义?
    淘宝(tmall)店铺旗舰店商品数据分析接口代码教程
    字体设计软件 Glyphs 2 mac中文版软件特点
    java基于微信小程序的加油站加油服务系统uni-app
    智慧金融-数据可视化
    FITC标记的大鼠抗小鼠CD11b抗体,FITC Rat Anti-Mouse CD11b
  • 原文地址:https://blog.csdn.net/m0_64158084/article/details/128001500