【贪心】橘子结配

题目:橘子结配 rqnoj121

题目描述

深秋来临,这是辛勤了一年享受丰收的季节,freeze大牛在闲暇时间来到郊外的橘园,想在美丽的秋景中体味丰收的欣喜与温暖。
这个橘园一共种有若干个橘子,现在他们想利用一天的时间,将其中一棵橘子树上的所有橘子都摘下来装入到一个大篮子中,他们根据过去的经验认为,一个篮子即使再大,它也有自己能装橘子的一个最大承受质量,他们在想只要能使能装入的橘子总质量最大(也就是不超过篮子的最大承受质量的最大装橘总质量)就算完成了任务。
但是这个橘园内种的橘子又有一个独特的性质:橘子可以互相结配(可以任意地结配,但是在第一次结配时,也就是结配的2个都是未结配的橘子,至少要有1个橘子已经从树上摘了下来,后面由于这棵橘子树就已经掌握了摘取本领,也就不再需要摘取橘子,就可以直接进行结配了),而且在结配或摘取的时候本身会产生一个损耗值(本题所述的损耗值均为其包含的所有橘子子损耗值的总合,橘子包含未结配与结配2种形态)。
所以此时即使想使能装入的橘子总质量最大,也会因为橘子质量本身发生损耗而减小,现在他们必须先算出这些橘子的最小损耗总值才能开始摘取,以保证其质量。
[数据规模]
n<=50
r最大不超过1000
From 宜昌6中(初中)

输入格式

输入有2行,
第1行1个数,即这棵橘子树上共有n个橘子;
第2行n个数,即这棵橘子树上每个橘子的损耗值r。

输出格式

输出有2行,
第一行首先算出这些橘子的最小损耗总值;
第二行判断它是否是素数,如果是,则输出Yes,否则输出No。

样例输入

样例输出

 

跟noip那道果子合并一样,只不过多了一个摘取的消耗值,total加上最小的那个值就行了。。。最后再判断是否是素数。

C++ Code

#include<cstdio>
#include<queue>
using namespace std;
#define oo 99999999
#define MAXN 100

int n,a[MAXN];
queue<int> q1,q2;

void qs(int l,int r)
{
  int i=l,j=r,x=a[i+(j-i)/2];
  do 
  {
    while(a[i]<x) i++;
    while(a[j]>x) j--;
    if(i<=j)
    {
      swap(a[i],a[j]);
      i++;j--;
    }
  }
  while(i<=j);
  if(i<r)qs(i,r);
  if(l<j)qs(l,j);
}

int getmin()
{
  int x,y;
  if(q1.empty()){x=q2.front();q2.pop();return x;}
  if(q2.empty()){x=q1.front();q1.pop();return x;}
  x=q1.front();y=q2.front();
  if(x<=y){q1.pop();return x;}
  q2.pop();return y;
}

void issushu(int x)
{
  int i;
  for(i=2;i<x;i++)
    if(x%i==0)
    {
      printf("No\n");
      exit(0);
    }
  printf("Yes\n");
  exit(0);
}

int main()
{
  freopen("rqn121.in","r",stdin);
  freopen("rqn121.out","w",stdout);
  scanf("%d",&n);
  int i,min=oo;
  for(i=1;i<=n;i++)
    scanf("%d",&a[i]);
  qs(1,n);
  for(i=1;i<=n;i++)q1.push(a[i]);
  int x,total=a[1];//摘取最小的耗费最小 
  for(i=1;i<n;i++)
  {
    x=getmin()+getmin();
    q2.push(x);
    total+=x;
  }
  printf("%d\n",total);
  issushu(total);
  return 0;
}

 

 

posted @ 2012-08-17 11:31  jiangzh  阅读(375)  评论(0)    收藏  举报