• Educational Codeforces Round 135 (Rated for Div. 2) E. Red-Black Pepper(贪心+数论)


     

     

    题解

    缝合题

    第一段是贪心求出所有红黑胡椒粉分配个数的最大价值

    第二段是数论求出可行解中的最优解

    第一段:

    假设我们全选bi,那么枚举下一种胡椒粉分配时,会把一个bi换成ai

    所以直接按照ai-bi大小排序

    这样可以保证每次选择的bi换位ai是最优的

    第二段:

    一个a胡椒粉套装含x包,一个b胡椒粉套装含y包

    exgcd求出来x*p+y*q=n的一个特解

    接下来我们应该枚举所有的可行解

    p=p0+k*y/gcd

    q=q0-k*x/gcd

    可惜直接枚举会超时

    我们发现第一段的答案是一个上凸函数

    我们可以三分

    可惜太麻烦了

    我们发现第一段答案的最高点的位置就是ai-bi由正转负的位置

    所以可以通过数学运算直接解出极值点附近的k

    然后为了保证正确性,我们枚举一下这个k附近的所有解就好了

    代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. #define N 300005
    7. struct node{
    8. int a,b;
    9. bool operator < (const node &t)const{
    10. return a-b>t.a-t.b;
    11. }
    12. }dish[N];
    13. #define LL long long
    14. LL ans[N];
    15. void exgcd(LL a,LL b,LL &gcd,LL &x,LL &y)
    16. {
    17. if(!b){x=1;y=0;gcd=a;}
    18. else{
    19. exgcd(b,a%b,gcd,y,x);
    20. y-=x*(a/b);
    21. }
    22. }
    23. int main()
    24. {
    25. int n,i;LL sum=0;
    26. scanf("%d",&n);
    27. for(i=1;i<=n;i++){
    28. scanf("%d%d",&dish[i].a,&dish[i].b);
    29. sum+=1ll*dish[i].b;
    30. }
    31. sort(dish+1,dish+n+1);
    32. ans[0]=sum;
    33. int chp=0;
    34. for(i=1;i<=n;i++){
    35. sum=sum-dish[i].b+dish[i].a;
    36. if(dish[i].a-dish[i].b>=0)
    37. chp=i;
    38. ans[i]=sum;
    39. }
    40. //printf("chp:%d\n",chp);
    41. int m;
    42. LL gcd,x,y,p,q;
    43. scanf("%d",&m);
    44. for(i=1;i<=m;i++){
    45. scanf("%lld%lld",&x,&y);
    46. exgcd(x,y,gcd,p,q);//xp+yq=gcd(x,y)
    47. if(n%gcd!=0)
    48. printf("-1\n");
    49. else{
    50. LL tmp=1ll*n/gcd;
    51. p*=tmp;q*=tmp;
    52. //xp+yq=n
    53. //x*p'=x*(p+k*y/gcd) = chp
    54. //q'=q-k*x/gcd
    55. //printf("pq::%lld %lld\n",p,q);
    56. LL k=floor(1.0*(1.0*chp/x-p)/y*gcd);
    57. LL realans=-1;
    58. for(LL K=k-3;K<=k+3;K++)
    59. if(x*(p+K*y/gcd)>=0&&x*(p+K*y/gcd)<=n&&y*(q-K*x/gcd)>=0&&y*(q-K*x/gcd)<=n)
    60. realans=max(realans,ans[x*(p+K*y/gcd)]);
    61. printf("%lld\n",realans);
    62. }
    63. }
    64. }

  • 相关阅读:
    项目风险管理的5大关键点,你做了几点?
    从C语言到C++_36(智能指针RAII)auto_ptr+unique_ptr+shared_ptr+weak_ptr
    迅为龙芯3A5000主板,支持PCIE 3.0、USB 3.0和 SATA 3.0显示接口2 路、HDMI 和1路 VGA,可直连显示器
    10_libpcap以及libnet
    img标签如何将<svg></svg>数据渲染出来
    idea灰屏问题
    sentinel-dashboard-1.8.0.jar开机自启动脚本
    五、Spring Boot(1)
    利用电商数据API接口上货、铺货
    onnx文件及其结构、正确导出onnx、onnx解析器
  • 原文地址:https://blog.csdn.net/C20180602_csq/article/details/126778321