这道题题解有很多,但我发现大多数都是错误的,下面是我的理解,恭迎大牛来判别正误。
下面我就列举错误代码:
#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 ; }
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; }