当前位置:   article > 正文

codeforce #381 ABC题解_381abccom

381abccom

不去吐槽自己的英文水平,不去吐槽自己的思维局限,只说题目意思和解法


A题

题意:我现在有n本书,现在有3种书的套装可以买,a元买1本的套装,b元买2本的套装,c元买3本的套装,套装不能拆开卖。问:我最少需要花多少钱,可以使得我的书的总数可以被4整除

分析:n如果直接是4的倍数,答案是0;余数分三种情况:

余数为3:买1本?!不一定!买5本?!买9本?!

因为要求是花最少的钱,那么买多少本书其实不重要,有多少种花钱方式比较重要(类似dp的思维)

买1本:花a元;买5本,花b+c元;买9本,花3*c元(这些都是有可能构成最小花费的)

余数为2和余数为1也是相同的思考方法

来说两种代码:一种dp,一种枚举的

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define LL __int64
  4. LL n,a,b,c,ans;
  5. LL dp[100];
  6. int main(){
  7. while(cin>>n>>a>>b>>c){
  8. dp[1]=a;
  9. dp[2]=min(dp[1]+a,b);
  10. dp[3]=min(c,min(dp[2]+a,dp[1]+b));
  11. for(int i=4;i<=10;i++)
  12. dp[i]=min(dp[i-1]+a,min(dp[i-2]+b,dp[i-3]+c));
  13. if (n%4==0) puts("0");
  14. else if (n%4==1) cout<<min(dp[3],dp[7])<<endl;
  15. else if (n%4==2) cout<<min(dp[2],dp[6])<<endl;
  16. else cout<<min(dp[1],min(dp[5],dp[9]))<<endl;
  17. }
  18. return 0;
  19. }
  20. #include<bits/stdc++.h>
  21. using namespace std;
  22. #define LL __int64
  23. LL n,a,b,c,ans;
  24. LL dp[100];
  25. int main(){
  26. while(cin>>n>>a>>b>>c){
  27. if (n%4==0) ans=0;
  28. else if (n%4==1){
  29. ans=c;
  30. ans=min(3*a,ans);
  31. ans=min(a+b,ans);
  32. }
  33. else if (n%4==2){
  34. ans=b;
  35. ans=min(a+a,ans);
  36. ans=min(c+c,ans);
  37. }
  38. else{
  39. ans=a;
  40. ans=min(b+c,ans);
  41. ans=min(3*c,ans);
  42. }
  43. cout<<ans<<endl;
  44. }
  45. return 0;
  46. }

B题:看懂了题的话,要求最大值:我们只需要去判断每个的计算是不是正的

要计算【a,b】区间内的和,必须用前缀和啊,所以就暴力跑一圈吧,注意初始化是0就好了


  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=150;
  4. int n,m;
  5. int a[maxn];
  6. int sum[maxn];
  7. int main(){
  8. while(scanf("%d%d",&n,&m)!=EOF){
  9. sum[0]=0;
  10. for(int i=1;i<=n;i++){
  11. scanf("%d",&a[i]);
  12. sum[i]=a[i]+sum[i-1];
  13. }
  14. int ans=0,u,v;
  15. while(m--){
  16. scanf("%d%d",&u,&v);
  17. if (sum[v]-sum[u-1]>0) ans+=sum[v]-sum[u-1];
  18. }
  19. printf("%d\n",ans);
  20. }
  21. return 0;
  22. }


C题:读题是个很麻烦的事情:重点应该是这句话的吧

The mex of a set S is a minimum possiblenon-negative integer that is not in S.

在集合S中mex这个值,是S集合中的没有出现过的最小的非负整数(会博弈论的话,SG函数要用这个)

m个区间中都取mex,然后找到这样的最大值

 

其实:答案很简单:就是最小的区间长度:想想为什么?

因为没有出现过的最小的非负整数!意思是:我们要想那个值最大,就必须从0开始起来编号对吧

拿第一个样例来说,我们必须0 1 0 1的编号,那么答案才会是2(最小的区间长度)

那么,这个题就成了简单构造题


  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,m,u,v;
  4. int main(){
  5. while(scanf("%d%d",&n,&m)!=EOF){
  6. int ans=n+1;
  7. while(m--){
  8. scanf("%d%d",&u,&v);
  9. ans=min(ans,v-u+1);
  10. }
  11. printf("%d\n",ans);
  12. for(int i=1;i<=n;i++)
  13. printf("%d%c",i%ans,i==n?'\n':' ');
  14. }
  15. return 0;
  16. }



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/503216
推荐阅读
相关标签
  

闽ICP备14008679号