Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1559204
  • 博文数量: 327
  • 博客积分: 10000
  • 博客等级: 上将
  • 技术积分: 3556
  • 用 户 组: 普通用户
  • 注册时间: 2005-04-05 21:28
个人简介

东黑布衣,流浪幽燕。 真诚善良,值得信赖。

文章分类

全部博文(327)

我的朋友

分类: BSD

2018-03-28 16:27:33

一. 贪心算法
C++
  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include <algorithm>
  4. using namespace std;
  5. const int maxn=1e3+5;
  6. const int maxx=1e5+100;
  7. struct node
  8. {
  9.     int x,y,id;
  10. }Q[maxx];

  11. bool cmp(node a,node b)
  12. {
  13.     return a.x>b.x;
  14. }
  15. int main(int argc, char* argv[])
  16. {
  17.     int n;
  18.     freopen("0798Di.txt","r",stdin);
  19.     cin>>n;
  20.     for(int i = 1 ; i <= n ; i++)
  21.     {
  22.         cin >> Q[i].x;
  23.         Q[i].id = i;
  24.     }
  25.     for(int i = 1 ; i <= n ; i++)
  26.         cin >> Q[i].y;
  27.     sort(Q+1,Q+n+1,cmp);
  28.     cout << n / 2 + 1 << endl;
  29.     cout <<Q[1].id;
  30.     if(n % 2 == 0)
  31.     {
  32.         for(int i=2;i<n-1;i+=2)
  33.         {
  34.             if(Q[i].y<Q[i+1].y)
  35.                 printf(" %d",Q[i+1].id);
  36.             else printf(" %d",Q[i].id);
  37.         }
  38.         printf(" %d",Q[n].id);
  39.     }
  40.     else
  41.     {
  42.         for(int i=2;i<n;i+=2)
  43.         {
  44.             if(Q[i].y<Q[i+1].y)
  45.                 printf(" %d",Q[i+1].id);
  46.             else printf(" %d",Q[i].id);
  47.         }
  48.     }
  49.     return 0;
  50. }
  51. /*
  52. 5
  53. 8 7 4 8 3
  54. 4 2 5 3 7
  55. 3
  56. 1 4 5
  57. */

C code begin

  1. #include <stdio.h>

  2. const int maxn=1e3+5;
  3. const int maxx=1e5+100;
  4. typedef struct node
  5. {
  6.    int x,y,id;
  7. }Tque;

  8. Tque Q[maxx];

  9. void quick_sort(Tque Q[], int l, int r)
  10. {
  11.    int i,j;
  12.    Tque val;
  13.    if(l<r){
  14.       i=l;
  15.       j=r;
  16.       val.x=Q[l].x;
  17.       val.y=Q[l].y;
  18.       val.id=Q[l].id;
  19.       while(i<j){
  20.          while(i<j && Q[j].x <= val.x)
  21.             j--;
  22.          if(i<j){
  23.             Q[i].x=Q[j].x;
  24.             Q[i].y=Q[j].y;
  25.             Q[i].id=Q[j].id;
  26.             i+=1;
  27.          }
  28.          while(i<j && Q[i].x > val.x)
  29.             i++;
  30.          if(i<j){
  31.             Q[j].x=Q[i].x;
  32.             Q[j].y=Q[i].y;
  33.             Q[j].id=Q[i].id;
  34.             j-=1;
  35.          }
  36.       }

  37.       Q[i].x=val.x;
  38.       Q[i].y=val.y;
  39.       Q[i].id=val.id;
  40.       quick_sort(Q,l,i-1);
  41.       quick_sort(Q,i+1,r);
  42.    }
  43. }

  44. int main(int argc, char* argv[])
  45. {
  46.    int n;
  47.    int i;
  48.    freopen("0798Di.txt","r",stdin);
  49.    scanf("%d", &n);
  50.    for(i=1;i<=n;i++)
  51.    {
  52.       scanf("%d", &Q[i].x);
  53.       Q[i].id = i;
  54.    }
  55.    for(i=1;i<=n;i++)
  56.       scanf("%d", &Q[i].y);

  57.    quick_sort(Q,1,n);
  58.    printf("%d\n%d", n/2+1, Q[1].id);
  59.    if(n%2 == 0)
  60.    {
  61.       for(i=2;i<n-1;i+=2)
  62.       {
  63.          if(Q[i].y<Q[i+1].y)//每次取出两个,比较y值,取y值大的
  64.             printf(" %d",Q[i+1].id);
  65.          else printf(" %d",Q[i].id);
  66.       }
  67.       printf(" %d",Q[n].id);
  68.    }
  69.    else
  70.    {
  71.       for(i=2;i<n;i+=2)
  72.       {
  73.          if(Q[i].y<Q[i+1].y)//每次取出两个,比较y值,取y值大的
  74.             printf(" %d",Q[i+1].id);
  75.          else printf(" %d",Q[i].id);
  76.       }
  77.    }
  78.    return 0;
  79. }
  80. /*
  81. in:
  82. 5
  83. 8 7 4 8 3
  84. 4 2 5 3 7
  85. out:
  86. 3
  87. 1 4 5
  88. */
C code end

二. 随机算法

  1. #include "stdafx.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>

  4. const int maxn=1e3+5;
  5. const int maxx=1e5+100;

  6. int a[maxx],b[maxx],c[maxx];

  7. void swap(int &a, int &b)
  8. {
  9.    int t; t=b; b=a; a=t;
  10. }

  11. void random_shuffle(int array[], int len)
  12. {
  13.    int i;
  14.    int j;
  15.    for(i=1;i<len;i++){
  16.       j=rand()%(i+1);
  17.       swap(array[i],array[j]);
  18.    }
  19. }

  20. int main(int argc, char* argv[])
  21. {
  22.    int i,n,p;
  23.    long long sum1=0,sum2=0,fa=0,fb=0;
  24.    freopen("0798Di.txt","r",stdin);
  25.    scanf("%d", &n);
  26.    p=n/2+1;

  27.    for(i=1;i<=n;i++){
  28.       scanf("%d", &a[i]);
  29.       c[i]=i;
  30.       sum1+=a[i];
  31.    }
  32.    for(i=1;i<=n;i++){
  33.       scanf("%d", &b[i]);
  34.       sum2+=b[i];
  35.    }
  36.    printf("%d\n",p);
  37.    while(1){
  38.       random_shuffle(c+1,n);
  39.       for(i=1;i<=p;i++){
  40.          fa+=a[c[i]];
  41.          fb+=b[c[i]];
  42.       }
  43.       if(2*fa>sum1 && 2*fb>sum2){
  44.          for(i=1;i<=p;i++)
  45.             printf("%d ",c[i]);
  46.          printf("%\n");
  47.          break;
  48.       }
  49.    }
  50.    return 0;
  51. }


三. 随机洗牌
将一个数组中的元素序列打算顺序进行重排,并需要保证重排后的每一种结果是等概率且随
机的。下面的两种算法哪一种是正确的?(注:random(a,b)返回一个a~b的随机整数)
1. for i=1 to n do swap( a[i], a[random(1,n)] );
2. for i=1 to n do swap( a[i], a[random(i,n)] );

解释:
首先,1~n的序列打乱重排共有n!个不同的排列,且每种排列被选中的概率为1/N!,只有这
样的算法才是等概率且随机的。

第一种算法将会产生n^n种情况,显然其中出现了重复的情况。那么会不会虽然出现重复,
但每种排列重复的次数相同,所以算法依然是等概率且随机的呢?答案是,不会。

假设上述情况成立,则n^n必定n!整除。但是,绝大多数情况下,n!的质因子远多于n^n的质
因子(即n的质因子。根据Bertrand-Chebyshev定理,在n/2和n之间一定还有一个质数。这
两个质数的乘积已经大于n了。搞了半天,第一种看似对称而美观的算法居然是错的!即对
所有大于2的n,上述整除都不不可能的。

第二种算法是符合要求的随机洗牌算法。

使用数学归纳法证明:

1、当n=1时,所以元素arr[0]在任何一个位置的概率为1/1,命题成立。
2、假设当n=k时,命题成立,即原数组中任何一个元素在任何一个位置的概率为1/k。

3、则当n=k+1时,当算法执行完k次时,前k个元素在前k个位置的概率均为1/k。当执行最后
   一步时,前k个元素中任何一个元素被替换到第k+1位置的概率为:
      (1-1/(k+1)) * 1/k = 1/(k+1);
   在前面k个位置任何一个位置的概率为
       (1-1/(k+1)) * 1/k = 1/(k+1);
    故前k个元素在任意位置的的概率都为1/(k+1)所以,对于前k个元素,
    它们在k+1的位置上概率为1/(k+1)。对于第k+1个元素,其在原位置的概率为1/k+1,在
    前k个位置任何一个位置的概率为:(1-k/(k+1)) * (1/k)=1/(k+1),
   所以对于第k+1个元素,其在整个数组前k+1个位置上的概率也均为1/k+1。

综上所述,对于任意n,只要按照方案中的方法,即可满足每个元素在任何一个位置出现的
概率均为1/n。



阅读(1934) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

ZHLN2018-04-07 19:02:21

https://zhidao.baidu.com/question/1800625864889212667.html