zoukankan      html  css  js  c++  java
  • 【贪心】均分纸牌问题

    环形均分纸牌

    均分纸牌noip2002   

    N堆纸牌,每堆上有若干张,纸牌总数必为N的倍数。可以在任一堆上取若干张纸牌,然后移动。

    移牌规则:在编号为1堆上取的纸牌,只能移到编号为2的堆上;在编号为N的堆上取的纸牌,只能移到编号为N1的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。

    现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多

    第一堆牌相差的牌只能由第二堆牌承担(给予或索要)

    一堆一堆处理 只考虑后一堆(前一堆已经处理好 再处理它会造成浪费

    #include<bits/stdc++.h>
    using namespace std;
    #define rg register
    const int N=1e6+5,M=1e6+5,inf=0x3f3f3f3f,P=9999973;
    int n,a[N],x=0,ans=0;
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int main(){
        rd(n);
        for(int i=1;i<=n;++i) rd(a[i]),x+=a[i];
        x/=n;
        for(int i=1;i<=n;++i)
        if(a[i]-x) ++ans,a[i+1]+=(a[i]-x);
        printf("%d",ans);
        return 0;
    }

    [HAOI2008]糖果传递

    有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。求使所有人获得均等糖果的最小代价。

    假设标号为i的小朋友开始有Ai颗糖果,Xi表示第i个小朋友给了第i-1个小朋友Xi颗糖果,如果Xi<0,说明第i-1个小朋友给了第i个小朋友Xi颗糖果,X1表示第一个小朋友给第n个小朋友的糖果数量。 所以最后的答案就是ans=|X1| + |X2| + |X3| + ……+ |Xn|。 对于第一个小朋友,他给了第n个小朋友X1颗糖果,还剩A1-X1颗糖果;但因为第2个小朋友给了他X2颗糖果,所以最后还剩A1-X1+X2颗糖果。根据题意,最后的糖果数量等于ave,即得到了一个方程:A1-X1+X2=ave。

    对于第1个小朋友,A1-X1+X2=ave -> X2=ave-A1+X1 = X1-C1(假设C1=A1-ave,下面类似)

    对于第2个小朋友,A2-X2+X3=ave -> X3=ave-A2+X2=2ave-A1-A2+X1=X1-C2

    对于第3个小朋友,A3-X3+X4=ave -> X4=ave-A3+X3=3ave-A1-A2-A3+X1=X1-C3

    …… 对于第n个小朋友,An-Xn+X1=ave

    希望Xi的绝对值之和尽量小,即|X1| + |X1-C1| + |X1-C2| + ……+ |X1-Cn-1|要尽量小,注意到|X1-Ci|的几何意义是数轴上的点X1到Ci的距离,所以问题变成了:给定数轴上的n个点,找出一个到他们的距离之和尽量小的点,而这个点就是这些数中的中位数  (from 洛谷第一篇题解

    大概可以手推一遍就懂辽

    #include<bits/stdc++.h>
    using namespace std;
    #define Max(x,y) (x)<(y)?(y):(x)
    #define Min(x,y) (x)<(y)?(x):(y)
    #define ll long long
    #define Abs(x) (x)<0?-x:x;
    #define rg register
    const int N=1e6+5,M=1e6+5,inf=0x3f3f3f3f,P=9999973;
    int n;
    ll ans=0,a[N],sum[N],b[N],ave=0;
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int main(){
    //    freopen("in.txt","r",stdin);
        rd(n);
        for(int i=1;i<=n;++i) rd(a[i]),sum[i]=sum[i-1]+a[i];
        ave=sum[n]/n;
        for(int i=1;i<=n;++i) b[i]=b[i-1]-a[i]+ave;
        sort(b+1,b+n+1);
        ll mid;
        if(n%2) mid=b[n+1>>1];
        else mid=(b[n>>1]+b[n>>1|1])/2;
        for(int i=1;i<=n;++i) ans+=abs(mid-b[i]);
        printf("%lld",ans); 
        return 0;
    }
  • 相关阅读:
    hmailserver
    用数据库管理SERV-U的用户时,如何修改密码及原理
    一个jquery的图片下拉列表 ddSlick
    图片下拉列表
    mvc 用户控件 ascx 获取 View 页面的值
    asp.net mvc 通过修改路由规则来实现页面的URL多参数传递
    tips
    让ie6/7/8兼容css3的圆角阴影等特殊效果的方法 PIE1.0.0及placeholder在这些IE下生效的方法
    IE8下ckeditor无法正常使用,提示"例外被抛出且未被接住"的解决办法
    iis6 下发布MVC2项目的方法
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11285684.html
Copyright © 2011-2022 走看看