Noip2015普及组第四题 Salesman的解题报告

本文针对一道算法题目提出两种解决方案:一种为直接贪心算法,但时间复杂度过高;另一种为优化后的贪心算法,通过寻找特定规律减少计算量,最终实现高效求解。
noip2015解题报告 - 区庆亮 - oql
 【题意分析】
         咋一看,这一题可以用贪心做,但是,时间复杂度是O(n*n),只能过60%的数据。
【贪心算法】(超时,60分)
#include<cstdio>
#include<cstring>
using namespace std;
int n,i,ans,sum,o,j,maxy=0,p;
unsigned long long a[100003],b[100003],maxx=0;
bool bo[100003];
int main()
{
 freopen("salesman.in","r",stdin);
 freopen("salesman.out","w",stdout);
 scanf("%d",&n);
 for(i=1;i<=n;i++) scanf("%d",&a[i]);
 for(i=1;i<=n;i++) scanf("%d",&b[i]);
    p=0;
 memset(bo,1,sizeof(bo));
 for(i=1;i<=n;i++)
 {
  int maxo=0;
  for(j=1;j<=n;j++)
  if(bo[j]==1)
  {
   if(a[j]>p) p=a[j];
   if((p*2+b[j])>maxo) { maxo=p*2+b[j]; o=j;}
  }
  if(p<a[o]) p=a[o];
  bo[o]=0;
  if(a[o]>maxy) maxy=a[o];
  maxx+=b[o];
  printf("%lld\n",maxx+(maxy*2));
 }
 return 0;
}
下面是正解: 
  第一步:找出所有中的最大值,记录下标k
  第二步:在k的前面找ai的最大值与下标记录,在k的后面找ai+di*2的最大值与下标记录(预处理)
  第三步:比较二者选较大值,如果值在k的后面则将k的值改变
  第四步:打印当前答案,转(2),循环n-1次。
【正解程序】
#include<cstdio>
using namespace std;
int n,i,j,a[100010],b[100010],c[100010],t[100010];
int max,k1,k2,k,i1;
int main()
{
 freopen("salesman.in","r",stdin);
 freopen("salesman.out","w",stdout);
 scanf("%d",&n);
 for(i=0;i<n;i++)
  scanf("%d",&a[i]);
 for(i=0;i<n;i++)
  scanf("%d",&b[i]);
 max=k=-1;
 for(i=0;i<n;i++)
 if((a[i]*2)+b[i]>max)
 {
  max=(a[i]*2)+b[i];
  k=i;
 }
 printf("%d\n",max);
 c[n-1]=n-1;
 for(i=n-2;i>=0;i--)
 {
  if(a[i+1]*2+b[i+1]<a[i]*2+b[i])
   c[i]=i;
  else c[i]=c[i+1];
 }
 for(i=0;i<k;i++) t[b[i]]++;
 for(i=1;i<n;i++)
 {
  i1=k1=-1;
  if(k<n-1)
  {
   i1=c[k+1];
   k1=(a[i1]-a[k])*2+b[i1];
  }
  for(j=1000;j>=1;j--)
   if(t[j]>0)
   {
    k2=j;
    --t[j];
    break;
   }
  if(k1>k2)
  {
   max+=k1;
   k=i1;
   printf("%d\n",max);
  }
  else
  {
   max+=k2;
   printf("%d\n",max);
  }
 }
 return 0;
}

转载于:https://www.cnblogs.com/ouqingliang/p/9245336.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值