hdu 4293 Groups (dp,2012成都网络赛)

http://acm.hdu.edu.cn/showproblem.php?pid=4293

题意:

有 n 个人,可任意分成若干组,然后每个人各提供一个信息,表示他们组前面有多少个人,后面有多少个人。问最多有多少个信息是不冲突的。

 

题解:  dp;

首先 我们 可以将 这 n 个人的 位置 看作是 区间  1---n 这样  说  每一个人说  其所在的组 前面 有 a 个人 后面 有 b 个人 那么 他的 组就 就在 a+1 到 n - b ;

我们将 说的情况相同的  人数 记录下来 (按照 其端点大小排序),这样  问题就变为了  在 1--n  这个区间上 不相交的 (带权 )区间的 的 和的 权值 最大为 多少 ;

我们用 dp[i]  表示  以 第 i 组 结尾的  的 最多 有多少;  那么  dp[i] =   max(num[i] + dp[j])    0<=j < i;

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include< set>
 7 #include<map>
 8 #include<queue>
 9 #include<vector>
10 #include< string>
11  #define Min(a,b) a<b?a:b
12  #define Max(a,b) a>b?a:b
13  #define CL(a,num) memset(a,num,sizeof(a));
14  #define eps  1e-12
15  #define inf   10000000
16 
17 
18  // freopen("data.txt","r",stdin);
19  const  double pi  = acos(- 1.0);
20 typedef   __int64  ll;
21  const  int maxn =  510 ;
22  using  namespace std;
23 
24  int dp[maxn],mat[maxn][maxn],num[maxn][maxn] ;
25  struct node
26 {
27      int s;
28      int t;
29 
30 
31 }p[maxn];
32 
33 
34  int cmp(node a,node b)
35 {
36       if(a.t != b.t )  return a.t < b.t;
37       else  return a.s < b.s ;
38 }
39  int main()
40 {
41      int  n,i,f,b,a,j;
42      while(scanf( " %d ",&n)!=EOF)
43     {
44 
45         CL(num ,  0 );
46          int  cnt =  0 ;
47          for(i =  0 ;i < n;i++)
48         {
49             scanf( " %d%d ",&a,&b);
50              if(a + b +  1 > n ||  num[a+  1][n - b] == n - a - b) continue ; // 注意 这的 判断 条件
51              
52              if(!num[a +  1][n - b])
53             {
54 
55                 p[cnt].s = a +  1 ;
56                 p[cnt++].t = n - b ;
57             }
58             num[a+ 1][n - b]++ ;
59 
60         }
61         sort(p,p+cnt,cmp);
62         CL(dp, 0) ;
63          int s = p[ 0].s;
64          int t = p[ 0].t ;
65         dp[ 0] = num[s][t] ;
66          for(i =  1 ; i < cnt;i++)
67         {
68             s = p[i].s;
69             t = p[i].t;
70             dp[i] = num[s][t] ;
71              for(j = i -  1;j >= 0;j--)
72             {
73                  if(p[j].t < s)
74                 {
75                     dp[i] = max(dp[i],num[s][t]+ dp[j]) ;
76                 }
77             }
78 
79 
80         }
81          int ans = - 1;
82          for(i =  0 ; i < cnt;i++)
83         {
84             ans = max(ans,dp[i]) ;
85         }
86         printf( " %d\n ",ans) ;
87 
88     }
89 }

 


你可能感兴趣的:(group)