• CF 303C——Minimum Modular——————【剪枝】


    Minimum Modular
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You have been given n distinct integers a1, a2, ..., an. You can remove at most k of them. Find the minimum modular m (m > 0), so that for every pair of the remaining integers(ai, aj), the following unequality holds: .

    Input

    The first line contains two integers n and k (1  ≤ n  ≤ 5000, 0 ≤ k ≤ 4), which we have mentioned above.

    The second line contains n distinct integers a1, a2, ..., an (0 ≤ ai ≤ 106).

    Output

    Print a single positive integer — the minimum m.

    Sample test(s)
    input
    7 0
    0 2 3 6 7 12 18
    output
    13
    input
    7 1
    0 2 3 6 7 12 18
    output
    7

    参考:http://www.cnblogs.com/Lyush/archive/2013/05/14/3077258.html

    题目大意:给你n个数,你可以从中删除最多k个数,使得剩余的所有数对m取余没有同余的,求最小的m。

    解题思路:首先想到暴力,从小到大枚举m,然后判断n个数中对m取模同余个数有多少,如果超出k就枚举更大的m。然而这样的话,时间复杂度为O(n*1e6)。然后在网上找了博客看,但是有些地方当时自己感觉很不好理解的,这里做下自己的解释。1.首先这里用了一个剪枝,这个剪枝能节省大量时间。因为如果有k+1个数都是对m取模同余,那么只需删除k个数,就可以让剩下的数(只剩下一个数)不同余,那么从k+1个同余的数中取出2个数组成同余对的组合数就有C(2,k+1)种,即k*k+1/2种,那么如果对m取模同余的同余对的组合数大于k*k+1/2种,说明无法删除k个数使得剩下的数不同余。2.然后暴力判断此时满足1步骤的m作为模是否能满足同余的数小于k个。

    #include<bits/stdc++.h>
    using namespace std;
    #define max(a,b) (a)>(b)?(a):(b)
    const int maxn=1e6+100;
    int num[maxn];
    int a[5500];
    bool flag[maxn];
    int dif(int a,int b){
       return  a>b? a-b:b-a;
    }
    int main(){
        int n,k,i,j,maxa,m,mark,sum,cn,mod;
        maxa=-1;
        while(scanf("%d%d",&n,&k)!=EOF){
            memset(num,0,sizeof(num));
            for(i=0;i<n;i++){
                scanf("%d",&a[i]);
                maxa=max(a[i],maxa);
            }
            //首先应知道a%m==b%m  -->  |a-b|%m==0
            for(i=1;i<n;i++){
                for(j=0;j<i;j++){
                    //不同类型的同余对各有多少
                    num[dif(a[i],a[j])]++;
                }
            }
            for(m=1;m<=maxa;m++){
                sum=0;
                for(i=m;i<=maxa;i+=m){  
                //这里i+=m的原因是,这样能保证同余对 对于对之间也都是同余的,即这样挑出的组合中所有数都是同余的。
                    sum+=num[i];        //
                    if(sum>k*(k+1)/2){  //剪枝
                        break;
                    }
                }
                if(sum>k*(k+1)/2){
                    continue;
                }
                cn=0,mark=0;
                for(j=0;j<n&&(!mark);j++){  //暴力判断m是否满足题目的要求
                    mod=a[j]%m;
                    if(!flag[mod]){
                        flag[mod]=1;
                    }else{
                        cn++;
                        if(cn>k){
                            mark=1;
                        }
                    }
                }
                for(j=0;j<n;j++){   //还原
                    flag[a[j]%m]=0;
                }
                if(!mark){
                    mark=m;
                    break;
                }
            }
            printf("%d
    ",mark);
        }
        return 0;
    }
    

      

  • 相关阅读:
    asp.net core 认证及简单集群
    Vue2.0 + Element-UI + WebAPI实践:简易个人记账系统
    Dapper关联查询
    sql模糊匹配中%、_的处理
    VS启用IIS调试的方法及可能碰到的问题。
    c#Winform程序,让pictureBox显示图像(包含GIF),并且不被占用,能即时删除图片。
    原创:无错版!让DEDE只生成一个RSS文件,不分栏目
    原创:js代码, 让dedecms支持Tag选择, 添加内容更为方便,不用手输Tag
    centos使用denyhosts的问题,会将自己的IP自动加到hosts.deny的解决办法。
    CentOS 5.6 netInstall可以的在线安装方式。
  • 原文地址:https://www.cnblogs.com/chengsheng/p/4543843.html
Copyright © 2020-2023  润新知