HDU 4293Groups(DP)

题目链接

转化真的是太神了,看了一下题解的提示,唉,真的是一个考验思维的题目。

题目大意:n个人一起走,可以分成很多组,每个人说一句话,前面有几个人,后面有有几个人,最多有多少个人说真话。

网赛的时候真心一点想法都没有啊,不知从何下手。。。看了一下题解的提示,这个问题只要转化一下,就是自己可以解决的问题了。每个人说的话,转化为一个区间,只需求最大不重叠区间的数目就可以了,这样就是以前做过的,排序后的线性的DP问题。敲的出来WA1次了,好在想了想有没有漏的情况,检查了出来,注意一下区间相同的时候的情况搞了个标记数组乱搞一下,2Y。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 struct node
 7 {
 8     int str;
 9     int end;
10 }p[501];
11 int cmp(const node &a,const node &b)
12 {
13     if(a.str < b.str)
14     return 1;
15     else if(a.str > b.str)
16     return 0;
17     else if(a.end < b.end)
18     return 1;
19     else
20     return 0;
21 }
22 int dp[501],o[501];
23 int main()
24 {
25     int i,j,k,n,a,b,num,ret;
26     while(scanf("%d\n",&n)!=EOF)
27     {
28         memset(dp,0,sizeof(dp));
29         memset(o,0,sizeof(o));
30         num = 0;
31         for(i = 1;i <= n;i ++)
32         {
33             scanf("%d%d",&a,&b);
34             if(a+1 <= n-b)
35             {
36                 p[num].str = a+1;
37                 p[num].end = n-b;
38                 num ++;
39             }
40         }
41         sort(p,p+num,cmp);
42         dp[0] = 1;
43         for(i = 1;i < num;i ++)
44         {
45             ret = 0;
46             for(j = 0;j < i;j ++)
47             {
48                 if(p[i].str > p[j].end)
49                 {
50                     if(ret < dp[j])
51                     {
52                         ret = dp[j];
53                         k = j;
54                     }
55                 }
56                 if(p[i].str == p[j].str&&p[i].end == p[j].end)
57                 {
58                     if(ret < dp[j]&&o[j] < p[i].end - p[i].str)
59                     {
60                         ret = dp[j];
61                         k = j;
62                     }
63                 }
64             }
65             if(p[i].str == p[k].str&&p[i].end == p[k].end)
66             {
67                 o[i] = o[k] + 1;
68             }
69             dp[i] = ret+1;
70         }
71         ret = 0;
72         for(i = 0;i < num;i ++)
73         {
74             if(ret < dp[i])
75             {
76                 ret = dp[i];
77             }
78         }
79         printf("%d\n",ret);
80     }
81     return 0;
82 }

转载于:https://www.cnblogs.com/naix-x/archive/2012/10/16/2725713.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值