题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1502
题目大意:找出总的满足条件的字符串数,num(a)=num(b)=num(c)且任何前缀均满足num(a)>=num(b)>=num(c)
解题思路:用dp[i][j][k]表示a取i个,b取j个,c取k个的状态下最多有多少种满足条件的情况,容易推得状态转移方程如下:
dp[i][j][k]=dp[i-1][j][k](i>j时)+dp[i][j-1][k](j>k时)+dp[i][j][k-1](k>0时)
根据该状态转移方程即可输出最后的结果dp[n][n][n]
因为本题的数据结果比较大,所以还需要用到高精度,对不会用java的人就只能手敲一个大数相加了。。。
1
#include<cmath>
2
#include<cstdio>
3
#include<cstring>
4
#include<iostream>
5
#include<algorithm>
6
#define
scan(a) scanf("%d",&a)
7
using
namespace
std;
8
#define
N 61
9
char
dp[N][N][N][
100
],a[
100
];
10
void
init()
11
{
12
strcpy(dp[
0
][
0
][
0
],
"
1\0
"
);
13
strcpy(dp[
1
][
1
][
0
],
"
1\0
"
);
14
strcpy(dp[
1
][
0
][
1
],
"
0\0
"
);
15
strcpy(dp[
1
][
0
][
0
],
"
1\0
"
);
16
}
17
18
void
add(
char
*
p)
19
{
20
int
x,l,i,jin=
0
;
21
l=
strlen(a);
22
int
now=
0
;
23
for
(i=
0
;p[i]!=
'
\0
'
;i++
)
24
//
从加数开始一位一位访问
25
{
26
if
(i>=
l)
27
x=p[i]-
'
0
'
+jin;
//
i超过了a的长度
28
else
29
x=p[i]-
'
0
'
+a[i]-
'
0
'
+
jin;
30
if
(x>
9
)
31
{
32
jin=x/
10
;
33
x%=
10
;
34
}
35
else
36
jin=
0
;
37
a[now++]=x+
'
0
'
;
38
}
39
while
(jin)
40
{
41
if
(l<=
now)
42
{
43
a[now++]=(jin%
10
)+
'
0
'
;
44
jin/=
10
;
45
}
46
else
47
{
48
x=a[now]-
'
0
'
;
49
x+=
jin;
50
if
(x>
10
)
51
{
52
jin=x/
10
;
53
x%=
10
;
54
}
55
else
56
jin/=
10
;
57
a[now++]=x+
'
0
'
;
58
}
59
}
60
if
(now>
l)
61
a[now]=
'
\0
'
;
62
}
63
64
void
put(
int
x)
65
{
66
int
l=
strlen(dp[x][x][x]);
67
for
(
int
i=l-
1
;i>=
0
;i--
)
68
cout<<
dp[x][x][x][i];
69
cout<<endl<<
endl;
70
}
71
72
int
main()
73
{
74
int
i,j,k;
75
int
n;
76
init();
77
for
(i=
1
;i<=
60
;i++
)
78
{
79
for
(j=
0
;j<=i;j++
)
80
{
81
for
(k=
0
;k<=j;k++
)
82
{
83
a[
0
]=
'
0
'
;
84
a[
1
]=
'
\0
'
;
85
//
cout<<i<<' '<<j<<' '<<k<<endl;
86
//
cout<<dp[i-1][j][k]<<' '<<dp[i][j-1][k]<<' '<<dp[i][j][k-1]<<endl;
87
if
(i>j&&j>=
k)
88
add(dp[i-
1
][j][k]);
89
if
(j>
k)
90
add(dp[i][j-
1
][k]);
91
if
(k>
0
)
92
add(dp[i][j][k-
1
]);
93
strcpy(dp[i][j][k],a);
94
}
95
}
96
}
97
while
(~scanf(
"
%d
"
,&
n))
98
{
99
put(n);
100
}
101
return
0
;
102
}

