T 1 : P 1115 \tt T1:P1115 T1:P1115
状态:
d
p
i
dp_i
dpi 表示以
i
i
i 为结尾的最大子段和。
状态转移方程:
d
p
i
=
max
(
d
p
i
−
1
+
a
i
,
a
i
)
dp_i=\max(dp_{i-1}+a_i,a_i)
dpi=max(dpi−1+ai,ai)
初始状态:
d
p
1
=
a
1
dp_1=a_1
dp1=a1
错误原因:开 long long,要与
a
i
a_i
ai 比较,要么自己加上一个,要么自己自立门户。
T 2 : B 3637 \tt T2:B3637 T2:B3637
状态:
d
p
i
dp_i
dpi 表示以
i
i
i 结尾的最大上升子序列。
状态转移方程:
for(int i=1;i<=n;i++)
for(int j=1;j<=i-1;j++)
if(a[i]>a[j])
dp[i]=max(dp[j]+1,dp[i]);
初始状态:
d
p
i
=
1
dp_i=1
dpi=1
错误原因:初始状态,
d
p
i
=
1
dp_i=1
dpi=1
做对了,所以没有 \color{white}做对了,所以没有 做对了,所以没有
T 4 : P 1002 \tt T4:P1002 T4:P1002
状态:
d
p
i
,
j
dp_{i,j}
dpi,j 表示起点走到
(
i
,
j
)
(i,j)
(i,j) 的所有路径数。
状态转移方程:
for(int i=2;i<=n;i++)
for(int j=2;j<=m;j++)
if(vis[i][j]==false)
dp[i][j]=dp[i-1][j]+dp[i][j-1];
初始状态:
先要列好方向数组,将可以走到的,第
1
1
1 行第
1
1
1 列均设为
1
1
1,注意特判
(
1
,
1
)
(1,1)
(1,1) 可能重复。
for(int i=0;i<=8;i++)
{
int nx=mx+dx[i];
int ny=my+dy[i];
if(nx>=1&ny>=1&&nx<=bx&&ny<=by)
vis[nx][ny]=true;
}
if(vis[1][1]==false)
dp[1][1]=1;
for(int i=2;i<=bx;i++)
if(vis[i][1]==false)
dp[i][1]=dp[i-1][1];
for(int i=2;i<=by;i++)
if(vis[1][i]==false)
dp[1][i]=dp[1][i-1];
错误原因:初始状态的第 1 1 1 行第 1 1 1 列没有处理好。
T 5 : P 2758 \tt T5:P2758 T5:P2758
状态:
d
p
i
,
j
dp_{i,j}
dpi,j 表示将
A
\tt A
A 串的前
i
i
i 个字符,替换为
B
\tt B
B 串的前
j
j
j 个字符的最少操作次数。
状态转移方程:
每一个操作都用一个
d
p
dp
dp 数组来表示。
- 删除: d p i − 1 , j + 1 dp_{i-1,j}+1 dpi−1,j+1。把 A \tt A A 串的第 i i i 个字符删除,注意算一步 + 1 +1 +1。
- 插入: d p i , j − 1 + 1 dp_{i,j-1}+1 dpi,j−1+1。把 B \tt B B 串的第 j j j 个字符插入在 A \tt A A 串的最后面,注意算一步 + 1 +1 +1。
- 替换: d p i − 1 , j − 1 + 1 dp_{i-1,j-1}+1 dpi−1,j−1+1。把 A \tt A A 串的前 i − 1 i-1 i−1 个字符变为 B \tt B B 串的前 j − 1 j-1 j−1 个字符,注意算一步 + 1 +1 +1。
注意不变,也就是 d p i − 1 , j − 1 dp_{i-1,j-1} dpi−1,j−1。
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i]!=b[j])
dp[i][j]=min(dp[i-1][j],min(dp[i][j-1],dp[i-1][j-1]))+1;
else
dp[i][j]=min(dp[i-1][j-1],min(dp[i][j-1]+1,dp[i-1][j]+1));
初始状态:
注意
i
=
0
i=0
i=0 且
j
=
0
j=0
j=0 的情况,也就是将
A
\tt A
A 串的前
0
0
0 个字符,替换为
B
\tt B
B 串的前
j
j
j 个字符的最少操作次数与将
A
\tt A
A 串的前
i
i
i 个字符,替换为
B
\tt B
B 串的前
0
0
0 个字符的最少操作次数。
for(int i=1;i<=n;i++)
dp[i][0]=i;
for(int i=1;i<=m;i++)
dp[0][i]=i;
错误原因:初始状态,又是初始状态!