牛人帮忙看一道题

FranklinChen-MSFT 2009-05-06 09:23:18
**********************************************************
Description

今年的国庆节是建国60周年大庆,学校要给一些建筑物挂上彩灯。彩灯的颜色有红色和黄色两种。现在这些彩灯已经连成了一条直线。需要从中间的某处断开,以分成若干段挂在不同的建筑物上。每段中或者全部是红灯,或者全部是黄灯,或者红灯和黄灯的数量相差不超过D。
问题是,这一串彩灯最少要分成几段。使得每段都满足上述条件。


Input

第一行是整数N和D,1<=N<=2500,1<=D<=N。
接下来的N行,按彩灯的顺序,描述彩灯的颜色,用R或Y表示。


Output

最少分成几段

Sample Input


14 3
R
Y
R
R
R
Y
R
Y
R
R
R
R
R
R

Sample Output

2
************************************************
希望用动态规划做
...全文
291 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
机智的呆呆 2009-05-11
  • 打赏
  • 举报
回复
up~~
appleshao 2009-05-11
  • 打赏
  • 举报
回复
求的是算法,没看懂楼主的意思.看了一半帮楼主顶顶
FranklinChen-MSFT 2009-05-11
  • 打赏
  • 举报
回复
16楼的时间太长,不能AC啊
aaaa3105563 2009-05-10
  • 打赏
  • 举报
回复
帮顶··
strive0 2009-05-10
  • 打赏
  • 举报
回复
up
yangjianghua 2009-05-10
  • 打赏
  • 举报
回复
up!
  • 打赏
  • 举报
回复
对这个问题我觉得应该首先从理论上给出解决方案:
我的意见供参考:
(1)将整个彩灯分成m个集合。其中每个集合里面的元素要么全是红灯,要么全是黄灯;
(2)在m各集合里面看那些能进行合并,将能合并的进行合并。
合并的原则:
1)向后合并;
2)合并后集合若满足数量相差不超过D,则将此集合记为新集合,同时删除合并前的集合;
3)对通一个集合,能向后合并的个数多久采用这种合并方案。
最后集合的个数则是问题的求解。
希望各位给点意见。
xsz88 2009-05-10
  • 打赏
  • 举报
回复
我顶,顶。
yangjianghua 2009-05-10
  • 打赏
  • 举报
回复
我写了一个:供参考

#include <iostream>
using namespace std;
#define INF 1000
int m[2500][2500];
int main()
{
int n,l=0;
int D;
cin>>n>>D;
char *s; s=new char[n];
for (l=0;l<n;l++)
{
cin>>s[l];
}
int i,j,k,R,Y;
for (i=0;i<n;i++)
{
R=0;Y=0;
for (j=i;j<n;j++)
{
if (s[j]=='R')
R++;
if (s[j]=='Y')
Y++;
m[i][i]=1;
if (R!=0 &&Y!=0 && abs(R-Y)>D) m[i][j]=INF;
if (R==0||Y==0) m[i][j]=1;
if (R!=0 &&Y!=0 && abs(R-Y)<=D) m[i][j]=1;
}

}

for (int r=2;r<=n;r++)
{
for (i=0;i<=n-r;i++)
{
j=i+r-1;
for (k=i;k<j;k++)
{
int t=m[i][k]+m[k+1][j];
if (t<m[i][j])
{
m[i][j]=t;
}
}
}
}
printf("%d\n",m[0][n-1]);
delete []s;
return 0;
}


其中递归定义最优解值:m[i][j]=min{m[i][j],m[i][k]+m[k+1][j]}
m[i][j]表示彩灯i到j的最小分段数。
然后自底向上计算m[i][j]。
有问题可以交流。
MMMoonriver 2009-05-10
  • 打赏
  • 举报
回复
up
stephenliu89 2009-05-09
  • 打赏
  • 举报
回复
我写的这道题的程序,为什么老是过不了OJ呢,牛人帮看看啊
#include <iostream>
#include <cmath>

using namespace std;
int N,D;
int pointer=0,way[2500][2500]={0,},point[250000]={0,};
char light[2500];


void func(int i,int n)
{
int j=i;

if (way[j][N-1]==0)
{
point[pointer]=n;
pointer++;
}
else
{
while(way[i][++j]==0 && pointer<100);

func(j,n+1);

}

}

int main()
{
int i,j,min=2500,R,Y;

cin >>N>>D;

for (i=0;i<N; i++)
cin>>light[i];

for (i=0;i<N;i++)
{
R=0;Y=0;
for(j=i;j<N;j++)
{
if(light[j]=='R')
R++;
if(light[j]=='Y')
Y++;


if ( R!=0 && Y!=0 && abs(R-Y)>D)
way[i][j]=1;
}
}

func(0,1);

for(i=0;i<=pointer;i++)
{
if(point[i]<min && point[i]>0)
min=point[i];
}

cout <<min<<endl;

return 0;
}
guanghong 2009-05-09
  • 打赏
  • 举报
回复
帮顶 关注。。。。
FranklinChen-MSFT 2009-05-09
  • 打赏
  • 举报
回复
8楼都想了4天啦!!大家帮帮我和他吧!!
Paradin 2009-05-07
  • 打赏
  • 举报
回复
mark.
早上看看。
fire_woods 2009-05-07
  • 打赏
  • 举报
回复
假设有a1,a2...an个点

定义D(i,j) = 1 如果从节点ai到aj数量差不超过D或者颜色全部相同
= n+1 否则(当然也可以当成不连通)

求的就是从a1到an的最短路径,如果>=n+1,则无解.
lzh9955 2009-05-06
  • 打赏
  • 举报
回复
顶起来!
jingjiwuci 2009-05-06
  • 打赏
  • 举报
回复
帮忙顶下
liliangbao 2009-05-06
  • 打赏
  • 举报
回复
等牛人~
mengde007 2009-05-06
  • 打赏
  • 举报
回复
再次顶;
  • 打赏
  • 举报
回复
帮顶。。acm

64,631

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧