zoukankan      html  css  js  c++  java
  • [机房测试] 堆石子

    Description

    给定 (nleq 35) 堆石子,可以把一些堆合并。合并之后,石子个数为这些堆石子个数和模 (Mod),求最终能得到的最大的石子个数。

    Solution

    最多有 (2^n) 种可能的石子个数,直接搜索不行。注意到背包的可合并性质,我们折半搜索。把石子分为两边,分别处理出所有可能值,这一步 (O(2^{frac{n}{2}}))。然后考虑合并,两堆石子 (0leq a+b <2 imes Mod),对所有值排序,分类讨论,枚举 (a),找到最大的 (b),使得 (a+b<Mod),用这个更新答案,之后可以用 two-pointer 解决。对于 (a+b>Mod) 的值,最后的值是 (a+b-Mod) 是小于 (Mod) 的,所以直接贪心地取最大的 (b) 更新答案。

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    
    const int N=20;
    const int M=1<<N;
    
    int L,Mod,A[N],B[N],n,m,a[M],b[M];
    
    void dfs(int *X,int *w,int st,int ed,int s){
        if(st==ed) w[++w[0]]=s;
        else dfs(X,w,st+1,ed,s),
             dfs(X,w,st+1,ed,(s+X[st])%Mod);
    }
    
    int main(){
        freopen("stone.in","r",stdin);
        freopen("stone.out","w",stdout);
        scanf("%d%d",&L,&Mod);
        n=L/2; m=L-n; int ans=0;
        for(int i=1;i<=n;i++) scanf("%d",&A[i]);
        for(int i=1;i<=m;i++) scanf("%d",&B[i]);
        dfs(A,a,1,n+1,0),dfs(B,b,1,m+1,0);
        sort(a+1,a+1+a[0]),sort(b+1,b+1+b[0]);
        for(int i=1;i<=b[0];i++) ans=max(ans,b[i]);
        for(int i=1;i<=a[0];i++) ans=max(ans,a[i]);
        int lt=1; while(lt<=b[0]&&a[1]+b[lt]<Mod) lt++; lt--;
        for(int i=1;i<=a[0];i++){
            while(lt&&b[lt]+a[i]>=Mod) lt--;
            ans=max(ans,a[i]+b[lt]);
            ans=max(ans,(a[i]+b[b[0]])%Mod);
        }
        printf("%d",ans);
    }
    
  • 相关阅读:
    51nod乘积之和
    Dell服务器安装OpenManage(OMSA)
    Nginx反向代理PHP
    搭建haproxy
    108. Convert Sorted Array to Binary Search Tree
    60. Permutation Sequence
    142. Linked List Cycle II
    129. Sum Root to Leaf Numbers
    118. Pascal's Triangle
    26. Remove Duplicates from Sorted Array
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15501083.html
Copyright © 2011-2022 走看看