2010-1145
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
题目大意,攻打来袭的敌人,攻打第i组敌人耗时ti,可以消灭敌人wi,求在T时间内最多可以消灭的敌人数,但有一个限制条件:告诉了每组敌人坐标和自己的坐标,对于位于一条线上的所有组敌人,每次攻打只能攻打离自己最近的那组。[[BR]]
背包问题,对于在一条线上的敌人,可以看做是一个物品处理,例如1,2,3这三组是在一条线上的敌人组,那把他们看做一个物品,要么攻打1,要么攻打1+2,要么攻打1+2+3,只能是选择一种这其中一种方案。[[BR]]
寻找位于一条线上敌人组的方法,我是利用斜率排序的(感觉此方法不佳),也可以用gcd来寻找。
{{{
#!cpp
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAX 10000000.00
using namespace std;
struct node
{
long x,y,t,w;
double k;
};
bool cmp(node x,node y) { return (x.k<y.k );}
bool cmp1(node x,node y){ if (x.x==y.x) return (x.y<y.y); else return (x.x<y.x ); }
int main()
{
long x0,y0,n,t0,j,k,i,midq,midh,i1,j1,k1,time,ren;
node a[600];
long f[10100];
while(scanf("%ld%ld%ld%ld",&x0,&y0,&n,&t0)!=EOF)
{
for (j=1;j<=n;++j)
{
scanf("%ld%ld%ld%ld",&k,&i,&a[j].t,&a[j].w);
a[j].x=k-x0;
a[j].y=i-y0;
if (k==x0) a[j].k=MAX; else a[j].k=1.00*(i-y0)/(k-x0);
}
sort(a+1,a+1+n,cmp);
i=1;j=1;
while(j<=n)
{
while(i<=n&&fabs(a[i].k-a[j].k)<0.00001) ++i;
sort(a+j,a+i,cmp1);
j=i;
}
memset(f,0,sizeof(f));
j=1;i=1;
while(j<=n)
{
while(i<=n && fabs(a[i].k-a[j].k)<0.00001) ++i;
midq=i-1;
midh=j;
if (a[j].k==MAX)
{
while(midq>=midh && a[midq].y>0) --midq;
midh=midq; midq++;
}
else
{
while(midq>=midh && a[midq].x>0) --midq;
midh=midq; midq++;
}
for (j1=t0;j1>=0;--j1)
{
time=0; ren=0;
for (i1=midq;i1<=i-1;++i1)
{
time+=a[i1].t; ren+=a[i1].w;
if (j1-time>=0&& f[j1-time]+ren>f[j1] ) f[j1]=f[j1-time]+ren;
}
}
for (j1=t0;j1>=0;--j1)
{
time=0; ren=0;
for (i1=midh;i1>=j;--i1)
{
time+=a[i1].t; ren+=a[i1].w;
if (j1-time>=0&& f[j1-time]+ren>f[j1] ) f[j1]=f[j1-time]+ren;
}
}
j=i;
}
printf("%ld\n",f[t0]);
}
return 0;
}
}}}
题目大意,攻打来袭的敌人,攻打第i组敌人耗时ti,可以消灭敌人wi,求在T时间内最多可以消灭的敌人数,但有一个限制条件:告诉了每组敌人坐标和自己的坐标,对于位于一条线上的所有组敌人,每次攻打只能攻打离自己最近的那组。
背包问题,对于在一条线上的敌人,可以看做是一个物品处理,例如1,2,3这三组是在一条线上的敌人组,那把他们看做一个物品,要么攻打1,要么攻打1+2,要么攻打1+2+3,只能是选择一种这其中一种方案。
寻找位于一条线上敌人组的方法,我是利用斜率排序的(感觉此方法不佳),也可以用gcd来寻找。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAX 10000000.00
using namespace std;
struct node
{
long x,y,t,w;
double k;
};
bool cmp(node x,node y) { return (x.k<y.k );}
bool cmp1(node x,node y){ if (x.x==y.x) return (x.y<y.y); else return (x.x<y.x ); }
int main()
{
long x0,y0,n,t0,j,k,i,midq,midh,i1,j1,k1,time,ren;
node a[600];
long f[10100];
while(scanf("%ld%ld%ld%ld",&x0,&y0,&n,&t0)!=EOF)
{
for (j=1;j<=n;++j)
{
scanf("%ld%ld%ld%ld",&k,&i,&a[j].t,&a[j].w);
a[j].x=k-x0;
a[j].y=i-y0;
if (k==x0) a[j].k=MAX; else a[j].k=1.00*(i-y0)/(k-x0);
}
sort(a+1,a+1+n,cmp);
i=1;j=1;
while(j<=n)
{
while(i<=n&&fabs(a[i].k-a[j].k)<0.00001) ++i;
sort(a+j,a+i,cmp1);
j=i;
}
memset(f,0,sizeof(f));
j=1;i=1;
while(j<=n)
{
while(i<=n && fabs(a[i].k-a[j].k)<0.00001) ++i;
midq=i-1;
midh=j;
if (a[j].k==MAX)
{
while(midq>=midh && a[midq].y>0) --midq;
midh=midq; midq++;
}
else
{
while(midq>=midh && a[midq].x>0) --midq;
midh=midq; midq++;
}
for (j1=t0;j1>=0;--j1)
{
time=0; ren=0;
for (i1=midq;i1<=i-1;++i1)
{
time+=a[i1].t; ren+=a[i1].w;
if (j1-time>=0&& f[j1-time]+ren>f[j1] ) f[j1]=f[j1-time]+ren;
}
}
for (j1=t0;j1>=0;--j1)
{
time=0; ren=0;
for (i1=midh;i1>=j;--i1)
{
time+=a[i1].t; ren+=a[i1].w;
if (j1-time>=0&& f[j1-time]+ren>f[j1] ) f[j1]=f[j1-time]+ren;
}
}
j=i;
}
printf("%ld\n",f[t0]);
}
return 0;
}