wa了若干次,自己的问题,与题目没什么关系。
输入的时候有很多问题,因为限制了左边的标号决定了右边的序号。
思路:
1.一开始按自己的动规思想做,越想越复杂。每次向前找符合的点,做不了
2.仔细看看,其实是动态规划的最长子序列问题(LIS)。
3.很多题解用了经典的二分搜索,手工写的,表示自己的理解不够火候,写不出,这种方法也与偏序集的思想有关
4.《训练指南》有介绍了这个方法,下面代码采用了这种模板的方法。不好理解,详见代码
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 using namespace std; 5 6 #define maxn 500010 7 #define INF 0x7fffffff 8 9 int rh[maxn],pr[maxn] , n ,ans; 10 int g[maxn],d[maxn]; 11 12 int dp(int *A) 13 { 14 memset(d,0,sizeof(d)); 15 for(int i=1;i<=n;i++) g[i] = INF; 16 for(int i=1;i<=n;i++){ 17 int k=lower_bound(g+1,g+n+1,A[i]) - g; 18 d[i] = k; 19 g[k] = A[i]; 20 } 21 int max = 0; 22 for(int i=1;i<=n;i++){ 23 if(max < d[i]) max = d[i]; 24 } 25 return max; 26 } 27 28 int main() 29 { 30 int cur=0; 31 while(~scanf("%d",&n)) 32 { 33 int r,p; 34 for(int i=1;i<=n;i++) scanf("%d%d",&r,&p),pr[r]=p; 35 ans=dp(pr); 36 printf("Case %d: ",++cur); 37 printf("My king, at most %d %s can be built. ", 38 ans ,ans>1?"roads":"road"); 39 } 40 return 0; 41 }