wyh123
解题思路记录和牢骚
C++博客
|
首页
|
发新随笔
|
发新文章
|
联系
|
聚合
|
管理
随笔:34 文章:1 评论:1 引用:0
HDOJ 1267(DP)
题目描述:给出m个H和n个D,求由这m个H和n个D组成的字符串满足“从左到右扫描该串,字符H的累计数总是不小于字符D的累计数”的方案数
解题思路:DP
显然,这里面可以把状态划分为dp[i][j],表示i个H和n个D含有多少成功的方案数。
那么它的转移方程就是: dp[i][j]=dp[i-1][j]+dp[i][j-1];
1)所有的串一定是以H或者D结尾
3)i>j,则dp[i][j]=0;
3)在成功的dp[i-1][j]后面中加上H,则这个是必然成立的。
4)关键是在成功的dp[i][j-1]后面中加上D。
如果此时恰好是i=j-1的话,加上D就错了~~,但问题是当i=j-1的时候i<j的根本不满足2),所以这个无须考虑的。
那么这里只有可能是i>j-1,所以加上了D,最坏的情况就是i=j,不会出现不满足题意的情况。
5)有人会认为可以通过一个不成功的串可以通过向其中加上一个H使其满足题设:
Eg:HDD+H=HDHD
这里给的反例是HDH+D=HDHD
其实很简单,HDD和HDH所出现的概率是相等的,所以一个不成功的串其中插入H势必会找到一个相对应的成功的串后面加上D
*写的时候也是凭感觉写出来,一做发现对了。后来才仔细的想了一下,其实转移也算是比较别扭的,不过总的来说这不是一道很难的DP题。
代码:
1
#include
<
iostream
>
2
#include
<
cstdio
>
3
#include
<
cstring
>
4
#include
<
cmath
>
5
6
using
namespace
std;
7
8
int
m,n;
9
long
long
dp[
50
][
50
];
10
11
int
main()
12
{
for
(
int
i
=
1
; i
<=
20
; i
++
)
13
dp[i][
1
]
=
i;
14
for
(
int
i
=
2
; i
<=
20
; i
++
)
15
for
(
int
j
=
2
; j
<=
20
; j
++
)
16
if
(i
>=
j)
17
dp[i][j]
=
dp[i][j
-
1
]
+
dp[i
-
1
][j];
18
else
19
dp[i][j]
=
0
;
20
while
(cin
>>
m
>>
n)
21
cout
<<
dp[m][n]
<<
endl;
22
23
return
0
;
24
}
25
发表于 2011-07-31 00:15
wyh
阅读(177)
评论(0)
编辑
收藏
引用
所属分类:
DP
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
相关文章:
poj 1042(DP)
poj 1036(DP)
poj 1015(DP)
HDOJ 1176(DP)
HDOJ 2041(DP)
HDOJ 2067(DP)
HDOJ 1267(DP)
网站导航:
博客园
IT新闻
BlogJava
知识库
博问
管理
<
2011年8月
>
日
一
二
三
四
五
六
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
给我留言
查看公开留言
查看私人留言
随笔分类
DP(8)
(rss)
比赛总结
(rss)
博弈
(rss)
二分
(rss)
模拟(3)
(rss)
数据结构
(rss)
数学(19)
(rss)
搜索(1)
(rss)
随笔档案
2011年8月 (19)
2011年7月 (15)
文章分类
DP
(rss)
模拟
(rss)
数据结构
(rss)
数论(1)
(rss)
搜索
(rss)
图论
(rss)
文章档案
2011年7月 (1)
搜索
最新评论
1. re: HDOJ 2067(DP)
压根就没有看懂题意的路过~~!
--wgh
阅读排行榜
1. poj 1015(DP)(1026)
2. HDOJ 2563(递推)(839)
3. poj 1029(模拟)(775)
4. HDOJ 1286(欧拉函数)(660)
5. poj 1042(DP)(650)
评论排行榜
1. HDOJ 2067(DP)(1)
2. HDOJ 2041(DP)(0)
3. 2011/7/31(0)
4. HDOJ 2044(DP)(0)
5. HDOJ 2563(递推)(0)