题目:TT 的奖励
题意:
输入:
多组样例。每组样例输入一个 m (0 < m < 100000),表示有 m 只猫咪。
在接下来的 m 行中,每行有两个整数 a b (0 < b < 100000),表示在第 b 秒的时候有一只猫咪掉落在 a 点上。
注意,同一个点上同一秒可能掉落多只猫咪。m = 0 时输入结束。
输出:
输出一个整数 x,表示 TT 可能接住的最多的猫咪数。
样例:
解题思路:dp题。首先,初始位置是5,知道第5秒才能跑完整个路径。同时可以设置f[i][j]为第i秒位置为j的接住的猫的最大的个数。然后f[i][j]=max(f[i-1][j],f[i-1][j-1],f[i-1][j+1])+k,k为在第i秒位置为j的掉的猫的个数。最后给出最大的f[i][j]就行了。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int f[100005][15],a[100005];
struct node
{
int pos,time;
}e[100005];
bool cmp(node a,node b)
{
if(a.time!=b.time){return a.time<b.time;}
return a.pos<b.pos;
}
int main()
{
while(1)
{
int m;
cin>>m;
if(m==0)break;
memset(f,0,sizeof(f));
memset(a,0,sizeof(a));
int maxn=0;
for(int i=1;i<=m;i++)
{
cin>>e[i].pos>>e[i].time;
e[i].pos++;
maxn=max(maxn,e[i].time);
}
sort(e+1,e+m+1,cmp);//按时间排序
for(int i=1;i<=m;i++)//记录每个时间最小位置的坐标
{
if(!a[e[i].time])
{
a[e[i].time]=i;
}
}
for(int i=1;i<=maxn;i++)
{
if(i<=5)//前5秒特殊对待
{
for(int j=6-i;j<=6+i;j++)
{
int k=0;
for(int u=a[i];u!=0&&e[u].time==i;u++)//求出在第i秒的j处的猫的个数
{
if(e[u].pos==j)
{
k++;
}else if(e[u].pos>j)
{
break;
}
}
f[i][j]=max(f[i-1][j-1]+k,f[i][j]);
f[i][j]=max(f[i-1][j]+k,f[i][j]);
f[i][j]=max(f[i-1][j+1]+k,f[i][j]);
}
continue;
}
for(int j=1;j<=11;j++)
{
int k=0;
for(int u=a[i];u!=0&&e[u].time==i;u++)
{
if(e[u].pos==j)
{
k++;
}else if(e[u].pos>j)
{
break;
}
}
f[i][j]=max(f[i-1][j-1]+k,f[i][j]);
f[i][j]=max(f[i-1][j]+k,f[i][j]);
f[i][j]=max(f[i-1][j+1]+k,f[i][j]);
}
}
int maxx=0;
for(int i=1;i<=11;i++)//给个最大就行了
{
maxx=max(maxx,f[maxn][i]);
}
cout<<maxx<<endl;
}
}