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 }

 


posted @ 2012-09-19 20:52  Szz  阅读(259)  评论(0编辑  收藏  举报