【动态规划】mr354-坐车看球

【题目大意】

两个球队的支持者要一起坐车去看球,他们已经排成了一列。我们要让他们分乘若干辆巴士,同一辆巴士上的人必须在队伍中是连续的。为了在车上不起冲突,希望两队的支持者人数尽量相等,差至多是D。有一个例外,就是一辆车上的人全部都是一个球队的支持者。问要将这N个人全部送至球场,至少要几辆巴士。第一行是整数N和D,1≤N≤2500,1≤D≤N。接下来的N行,按排队的顺序,描述每个人支持的球队,用H或J表示。

输出至少要几辆巴士。

样例输入

14 3

H

J

H

H

H

J

H

J

H

H

H

H

H

H

样例输出

2

【思路】

记录下到第i个人为止,支持两队的人的个数,接下来预处理[i,j]之间的人能否坐在一辆车上,如果它们能坐在一辆车上,必定满足以下三个条件中的一个:

(1)[i,j]均支持H队,即H[j]-H[i-1]==j-i+1;

(2)[i,j]均支持J队,即J[j]-J[i-1]==j-i+1;

(3)[i,j]支持H队和J队的人数差小于等于D,即|( H[j]-H[i-1])-( J[j]-J[i-1])|≤D。

预处理结束之后,依次判断区间[i,j],car[j]表示到第j个人为止最少需要多少辆车。如果[i,j]区间内的人能公用一辆车,则car[j]=min(car[j],car[i-1]+1)。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 using namespace std;
 5 const int MAXN=2500+50;
 6 int n,d;
 7 int can[MAXN][MAXN]; 
 8 int H[MAXN],J[MAXN];
 9 int car[MAXN];
10 
11 int main()
12 {
13     freopen("mr354.in0","r",stdin);
14     freopen("mr354.ou0","w",stdout);
15     scanf("%d%d",&n,&d);
16     memset(H,0,sizeof(H));
17     memset(J,0,sizeof(J));
18     memset(can,0,sizeof(can));
19     for (int i=1;i<=n;i++)
20     {
21         getchar();
22         char c;
23         scanf("%c",&c);
24         H[i]=H[i-1];
25         J[i]=J[i-1];
26         if (c=='H') H[i]++; else J[i]++;
27         car[i]=i;
28     }
29 
30     
31     for (int i=1;i<=n;i++)
32         for (int j=i;j<=n;j++)
33             if (H[j]-H[i-1]==j-i+1 || J[j]-J[i-1]==j-i+1 || abs((J[j]-J[i-1])-(H[j]-H[i-1]))<=d)
34                 can[i][j]=1;
35                 
36     for (int i=1;i<=n;i++)
37         for (int j=1;j<=i;j++)
38             if (can[j][i])
39                 car[i]=min(car[i],car[j-1]+1);
40                 
41     cout<<car[n]<<endl;
42     return 0;
43 }

转载于:https://www.cnblogs.com/iiyiyi/p/4736243.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值