1、poj1700过河问题
先排序,然后假设数据为t1 t2 t3 t4 t5 t6 t7 t8,只会有两种方式:
方式一:最快的两个作为划回的船,两个来回运走两个最慢的,好处是最慢的和次慢的组合消除掉次慢的时间,坏处是往回划的有一半是次快的。时间:t1+2*t2+t8
方式二:只有最快的作为划回的船,两个来回运走两个最慢的,好处是往回划的时间是最优的,坏处是往对岸划的次慢的时间也走了。时间:2*t1+t7+t8
综合两种情况,只需要把数据划分为1,2,3,大于4个这四种情况,大于4的时候比较方式一和二取最小值,1、2、3的时候单独讨论即可
#include <stdio.h>
#include <stdlib.h>
void sort(int *pe,int n)
{
int i,j;
int temp;
for(i=0;i<n;i++)
{
for(j=n-1;j>i;j--)
{
if(pe[j]<pe[j-1])
{
temp=pe[j];
pe[j]=pe[j-1];
pe[j-1]=temp;
}
}
}
}
int main()
{
int t,n;
int pe[1000];
int i;
int sum;
scanf("%d",&t);
while(t--)
{
sum=0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&pe[i]);
}
sort(pe,n);
while(n>0)
{
if(n==1)
{
sum+=pe[0];
n=0;
}else if(n==2)
{
sum+=pe[1];
n=0;
}else if(n==3)
{
sum+=(pe[1]+pe[0]+pe[2]);
n=0;
}else
{
int a1=pe[0]+pe[1]*2+pe[n-1];
int a2=pe[0]*2+pe[n-1]+pe[n-2];
sum+=a1<a2?a1:a2;
n-=2;
}
}
printf("%d\n",sum);
}
return 0;
}
2、poj1328海岸线问题
这是一道区间覆蓋类问题
第一步:输入时,求以海岛为圆心画圆与x轴的交点,两个交点之间放置雷达则可覆蓋该海岛,保存这些线段到数组。
第二步:按线段左起点递增排序
第三步:从后向前比较,若i和i-1有交集则更新为交集,若无交集则增加雷达
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void sort(double a[1000][2],int n)
{
int i,j;
double temp;
for(i=0;i<n;i++)
{
for(j=n-1;j>i;j--)
{
if(a[j][0]<a[j-1][0])
{
temp=a[j][0];
a[j][0]=a[j-1][0];
a[j-1][0]=temp;
temp=a[j][1];
a[j][1]=a[j-1][1];
a[j-1][1]=temp;
}
}
}
}
int main()
{
int n,d;
int i;
double co[1000][2];
int x1,x2;
int num,flag;
int t=1;
while(scanf("%d %d",&n,&d)!=EOF&&n&&d)
{
num=0;flag=0;
for(i=0;i<n;i++)
{
scanf("%d %d",&x1,&x2);
if(x2>d)
{
flag=1;
}
co[i][0]=x1-sqrt(pow(d,2)-pow(x2,2));
co[i][1]=x1+sqrt(pow(d,2)-pow(x2,2));
}
if(flag)
{
printf("Case %d: -1\n",t++);
}else
{
sort(co,n);
for(i=n-1;i>0;i--)
{
if(co[i][1]<=co[i-1][1])
{
co[i-1][0]=co[i][0];
co[i-1][1]=co[i][1];
}else if(co[i][0]<=co[i-1][1])
{
co[i-1][0]=co[i][0];
}else
{
num++;
}
}
printf("Case %d: %d\n",t++,num+1);
}
}
return 0;
}
3、poj2376
纯区间覆蓋类问题,上一题是分散的区间数量,这一题就是单纯的区间覆蓋了。按左端点从左到右覆蓋,每次选取剩余线段最大的。
这里[1,2]到[3,4]这种也可以链接。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,t;
int a[25000][2];
int i,j,temp[1][2];
int flag,num;
while(scanf("%d %d",&n,&t)!=EOF)
{
flag=1;
num=0;
for(i=0;i<n;i++)
{
scanf("%d %d",&a[i][0],&a[i][1]);
temp[0][0]=a[i][0];temp[0][1]=a[i][1];
for(j=i-1;j>=0&&(a[j][0]>temp[0][0]);j--)
{
a[j+1][0]=a[j][0];
a[j+1][1]=a[j][1];
}
a[j+1][0]=temp[0][0];
a[j+1][1]=temp[0][1];
}
if(a[0][0]>1)
{
flag=0;
}else
{
temp[0][0]=1;temp[0][1]=0;
int max=0;
for(i=0;i<n;i++)
{
if(a[i][0]<=temp[0][1]+1)
{
if(i==n-1)
{
if(temp[0][1]<a[i][1])
{
num++;
temp[0][1]=a[i][1];
}
}else
{
max=a[i][1]>max?a[i][1]:max;
}
}else
{
if(temp[0][1]<max)
{
num++;
temp[0][1]=max;
}
if(a[i][0]>temp[0][1]+1)
{
flag=0;
break;
}else if(i==n-1)
{
if(temp[0][1]<a[i][1])
{
num++;
temp[0][1]=a[i][1];
}
}else
{
max=a[i][1];
}
}
if(temp[0][1]==t) break;
}
}
if(temp[0][1]!=t) flag=0;
if(flag)
{
printf("%d\n",num);
}else
{
printf("-1\n");
}
}
return 0;
}