比赛的时候真心没想出来什么好的dp方法。。。蛋疼!整个比赛脑子发懵。。。!
dp[i][j]表示到第j个人,i到j是一个group时说真话的最大人数。num[a][b]统计出说前面有a个,后面有b个的人的个数,当然,不超过n - a - b;
dp[i][j] = max{dp[k][i]} + num[i][n-j];
ans = max{dp[k][n]};
ps:蛋疼的java.util.Arrays.fill(),妹的!内部函数就是一个for循环,只能初始化一维数组。。。表示以后再也不用了。。。
import java.util.*; public class Main { /** * @param args */ static final int N = 550; static int[][] num = new int[N][N]; static int[][] dp = new int[N][N]; static int[] pre = new int[N]; public static void main(String[] args) { Scanner cin = new Scanner(System.in); int n, a, b, i, j, ans; while(cin.hasNext()) { n = cin.nextInt(); for(i = 0; i <= n; ++i) { pre[i] = 0; for(j = 0; j <= n; ++j) { dp[i][j] = num[i][j] = 0; } } for(i = 0; i < n; ++i) { a = cin.nextInt(); b = cin.nextInt(); num[a][b] ++; if(num[a][b] > n - a - b) num[a][b] = n - a - b; } for(j = 0; j <= n; ++j) { for(i = 0; i < j; ++i) { dp[i][j] = pre[i]; dp[i][j] += num[i][n-j]; pre[j] = Math.max(pre[j], dp[i][j]); } } ans = 0; for(i = 0; i < n; ++i) { ans = Math.max(ans, dp[i][n]); } System.out.println(ans); } } }