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 }
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 }