这道题题解有很多,但我发现大多数都是错误的,下面是我的理解,恭迎大牛来判别正误。
下面我就列举错误代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std ;
int a [ 100001 ] [ 12 ] ;
int f [ 100001 ] [ 12 ] ;
int main () {
int n ;
while ( scanf( "%d" , &n )!= EOF && n ) {
memset ( a, 0 , sizeof ( a ) ) ;
memset ( f, 0 , sizeof ( f ) ) ;
int x, T, i, j, maxT = 0 , ans = 0 ;
while ( n -- ) {
scanf ( "%d%d" , & x, & T ) ;
++ a [ T ] [ x ] ;
maxT = max ( maxT, T ) ;
}
f [ 1 ] [ 4 ] = a [ 1 ] [ 4 ] ;
f [ 1 ] [ 5 ] = a [ 1 ] [ 5 ] ;
f [ 1 ] [ 6 ] = a [ 1 ] [ 6 ] ;
for ( i = 2 ; i <= maxT ; ++ i ) {
for ( j = 0 ; j < 11 ; ++ j ) {
f [ i ] [ j ] = f [ i - 1 ] [ j ] ;
if ( j > 0 )
f [ i ] [ j ] = max ( f [ i ] [ j ] , f [ i - 1 ] [ j - 1 ] ) ;
if ( j < 10 )
f [ i ] [ j ] = max ( f [ i ] [ j ] , f [ i - 1 ] [ j + 1 ] ) ;
f [ i ] [ j ]+=a [ i ] [ j ] ;
//printf("%d ", f[i][j]);
}
//printf("\n");
}
for ( i = 0 ; i < 11 ; ++ i )
ans = max ( ans, f [ maxT ] [ i ] ) ;
printf ( "%d \n " , ans ) ;
}
return 0 ;
}
上述代码如果交的话会ac,但是我认为这应是错误代码,因为
f [ i ] [ j ]+=a [ i ] [ j ] ;
这一句中,没有考虑是否能够到达,即使不能到达,改代码也会加上该时刻的馅饼数。
所以当你输入:
3
10 2
10 2
10 2
会输出3。
但正确答案应该是0,因为在第二秒根本无法到达10。
很多博客答案与此类似,希望大牛来讨论正误。
下面是我认为正确的代码:(是通过逆序时间来动态求解)
#include<stdio.h>
#include<cmath>
#include<algorithm>
using namespace std;
int dp[100005][12];
int main()
{
int n,i,j,maxt;
int x,t;
while(scanf("%d",&n),n)
{
maxt=0;
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
{
scanf("%d%d",&x,&t);
dp[t][x]++;
if(maxt<t) maxt=t;
}
for(i=maxt-1;i>=0;i--)
{
dp[i][0]+=max(dp[i+1][1],dp[i+1][0]);
for(j=1;j<11;j++)
{
dp[i][j]+=max(max(dp[i+1][j-1],dp[i+1][j]),dp[i+1][j+1]);
}
}
printf("%d\n",dp[0][5]);
}
return 0;
}