题目清单

acwing1049.大盗阿福
状态表示:
f
[
i
,
0
]
,
f
[
i
,
1
]
f[i,0],f[i,1]
f[i,0],f[i,1]
集合:考虑前i家店铺,第i家偷(1)或不偷(0)的方案。
属性:
m
a
x
max
max
状态计算:
d
p
[
i
]
[
0
]
=
m
a
x
(
d
p
[
i
−
1
]
[
0
]
,
d
p
[
i
−
1
]
[
1
]
)
dp[i][0]=max(dp[i-1][0],dp[i-1][1])
dp[i][0]=max(dp[i−1][0],dp[i−1][1])
d
p
[
i
]
[
1
]
=
d
p
[
i
−
1
]
[
0
]
+
w
[
i
]
)
dp[i][1] =dp[i-1][0]+w[i])
dp[i][1]=dp[i−1][0]+w[i])
状态机模型

#include <iostream>
using namespace std;
const int N = 100010;
const int INF = 0x3f3f3f3f;
int a[N];
int dp[N][2];
int main()
{
int t;
cin >> t;
while (t -- )
{
int n;
cin >> n;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
dp[0][0] = 0, dp[0][1] = -INF;
for (int i = 1; i <= n; i ++ )
{
dp[i][0] = max(dp[i - 1][1], dp[i - 1][0]);
dp[i][1] = dp[i - 1][0] + a[i];
}
cout << max(dp[n][0], dp[n][1]) << endl;
}
return 0;
}
acwing1057.股票买卖Ⅳ
状态表示:
f
[
i
,
j
,
0
]
,
f
[
i
,
j
,
1
]
f[i,j,0],f[i,j,1]
f[i,j,0],f[i,j,1]
集合:考虑前i天,第i持有股票且这是第j支股票/第i天没有持有股票且已经买卖j支股票的方案。
属性:
m
a
x
max
max
状态计算:
d
p
[
i
]
[
j
]
[
0
]
=
m
a
x
(
d
p
[
i
−
1
]
[
j
]
[
0
]
,
d
p
[
i
−
1
]
[
j
]
[
1
]
+
a
[
i
]
)
dp[i][j][0] = max(dp[i - 1][j][0], dp[i - 1][j][1] + a[i])
dp[i][j][0]=max(dp[i−1][j][0],dp[i−1][j][1]+a[i])
d
p
[
i
]
[
j
]
[
1
]
=
m
a
x
(
d
p
[
i
−
1
]
[
j
]
[
1
]
,
d
p
[
i
−
1
]
[
j
−
1
]
[
0
]
−
a
[
i
]
)
dp[i][j][1] = max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - a[i])
dp[i][j][1]=max(dp[i−1][j][1],dp[i−1][j−1][0]−a[i])
状态机模型

#include <iostream>
#include <cstring>
using namespace std;
const int N = 100010;
const int K = 110;
const int INF = 0x3f3f3f3f;
int dp[N][K][2];
int a[N];
int main()
{
int n, k;
cin >> n >> k;
memset(dp, -INF, sizeof dp);
for (int i = 0; i <= n; i ++ )
dp[i][0][0] = 0;
for (int i = 1; i <= n; i ++ )
cin >> a[i];
for (int i = 1; i <= n; i ++ )
{
for (int j = 1; j <= k; j ++ )
{
dp[i][j][0] = max(dp[i - 1][j][0], dp[i - 1][j][1] + a[i]);
dp[i][j][1] = max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - a[i]);
}
}
int res = 0;
for (int i = 0; i <= k; i ++ )
res = max(res, dp[n][i][0]);
cout << res << endl;
return 0;
}
acwing1058.股票买卖Ⅴ
状态表示:
f
[
i
,
0
]
,
f
[
i
,
1
]
,
f
[
i
,
2
]
f[i,0],f[i,1],f[i,2]
f[i,0],f[i,1],f[i,2]
集合:考虑前i天,第i天持仓(0),空仓(1),冷冻期(2)的方案。
属性:
m
a
x
max
max
状态计算:
d
p
[
i
]
[
0
]
=
m
a
x
(
d
p
[
i
−
1
]
[
0
]
,
d
p
[
i
−
1
]
[
1
]
−
a
[
i
]
)
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - a[i])
dp[i][0]=max(dp[i−1][0],dp[i−1][1]−a[i])
d
p
[
i
]
[
1
]
=
m
a
x
(
d
p
[
i
−
1
]
[
1
]
,
d
p
[
i
−
1
]
[
2
]
)
dp[i][1] = max(dp[i - 1][1], dp[i - 1][2])
dp[i][1]=max(dp[i−1][1],dp[i−1][2])
d
p
[
i
]
[
2
]
=
d
p
[
i
−
1
]
[
0
]
+
a
[
i
]
dp[i][2] = dp[i - 1][0] + a[i]
dp[i][2]=dp[i−1][0]+a[i]
状态机模型

#include <iostream>
#include <cstring>
using namespace std;
const int N = 100010;
const int INF = 0x3f3f3f3f;
int a[N];
int dp[N][3];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i ++ )
cin >> a[i];
dp[0][2] = -INF;
dp[0][0] = - INF;
dp[0][1] = 0;
for (int i = 1; i <= n; i ++ )
{
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - a[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][2]);
dp[i][2] = dp[i - 1][0] + a[i];
}
cout << max(dp[n][1], dp[n][2]) << endl;
return 0;
}
acwing.1052设计密码
状态表示:
f
[
i
,
j
]
f[i,j]
f[i,j]
集合:密码已经生成了i位,以i结尾的后缀和子串匹配长度为j的所有方案。
属性:
c
n
t
cnt
cnt
状态计算:

当第i+1位匹配子串的u位置时,
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]能够转移到
d
p
[
i
+
1
]
[
u
]
dp[i+1][u]
dp[i+1][u]
d
p
[
i
+
1
]
[
u
]
=
d
p
[
i
+
1
]
[
u
]
+
d
p
[
i
]
[
j
]
dp[i+1][u]=dp[i+1][u]+dp[i][j]
dp[i+1][u]=dp[i+1][u]+dp[i][j]
状态之间的转移关系用KMP算法进行匹配。
状态机模型

#include <iostream>
#include <cstring>
using namespace std;
const int N = 60;
const int MOD = 1e9 + 7;
int dp[N][N];
char str[N];
int ne[N];
int main()
{
int n;
cin >> n >> (str + 1);
int m = strlen(str + 1);
for (int i = 2, j = 0; i <= m; i ++ )
{
while (j && str[j + 1] != str[i]) j = ne[j];
if (str[j + 1] == str[i]) j ++ ;
ne[i] = j;
}
dp[0][0] = 1;
for (int i = 0; i < n; i ++ )
{
for (int j = 0; j < m; j ++ )
{
for (char k = 'a'; k <= 'z'; k ++ )
{
int u = j;
while (u && str[u + 1] != k) u = ne[u];
if (str[u + 1] == k) u ++ ;
if (u < m) dp[i + 1][u] = (dp[i + 1][u] + dp[i][j]) % MOD;
}
}
}
int res = 0;
for (int i = 0; i < m; i ++ )
res = (res + dp[n][i]) % MOD;
cout << res << endl;
return 0;
}

1737

被折叠的 条评论
为什么被折叠?



