OJ题目:click here~~
题目分析:n个人分为若干组 , 每个人描述其所在的组前面的人数和后面的人数。求这n个描述中,最多正确的个数。
设dp[ i ] 为前i个人的描述中最多正确的个数,则dp[ n ] 为要求的。num[ i ][ j ] 保存说前面有i个人 , 后面有j个人的人数,显然num[ i ][ j ]不超过n - i - j;
转移方程dp[ i ] = max(dp[ i ] , dp[ j ] + num[ j ][ n - i ]) ,详细解释见代码注释。
AC_CODE
int num[502][502];
int dp[502];
int main()
{
//freopen("in.txt","r",stdin);
int n;
while(cin >> n){
memset(num , 0 , sizeof(num));
memset(dp , 0 , sizeof(dp));
int i , j , a , b;
for(i = 1;i <= n;i++){
scanf("%d%d",&a,&b);
if(a+b < n && num[a][b] < (n - a - b)) num[a][b]++;
}
for(i = 1;i <= n;i++)//对于第i个人
for(j = 0;j < i;j++)//他可能表述为前面有j个人,j在[0 i-1],所以是dp[j] + num[j][]
dp[i] = max(dp[i] , dp[j] + num[j][n-i]);//为什么num的二维表示成[n-i]?这样可以保证2个for下来遍历所有该遍历的num[i][j]!!!
cout << dp[n] << endl;
}
return 0;
}