题目
题目刚看没啥思路,但是只要再看看就会知道,这就只是要维护后面的一项是否比前一项大,对于这一个该怎么去搞,今天才知道字符串也是可以进行比较的,比较的直接就是是字典序的大小。
然后就是dp的公式
f
[
i
]
[
1
]
=
m
i
n
{
f
[
i
−
1
]
[
0
]
(
a
[
i
]
≥
c
[
i
−
1
]
)
f
[
i
−
1
]
[
1
]
(
a
[
i
]
≥
a
[
i
−
1
]
)
f[i][1]=min\begin{cases}f[i-1][0](a[i]\ge c[i-1])\\f[i-1][1] (a[i] \ge a[i-1])\\\end{cases}
f[i][1]=min{f[i−1][0](a[i]≥c[i−1])f[i−1][1](a[i]≥a[i−1])
f
[
i
]
[
0
]
=
m
i
n
{
f
[
i
−
1
]
[
0
]
+
v
[
i
]
(
c
[
i
]
≥
c
[
i
−
1
]
)
f
[
i
−
1
]
[
1
]
+
v
[
i
]
(
c
[
i
]
≥
a
[
i
−
1
]
)
f[i][0]=min\begin{cases}f[i-1][0]+v[i](c[i]\ge c[i-1])\\f[i-1][1]+v[i] (c[i] \ge a[i-1])\\\end{cases}
f[i][0]=min{f[i−1][0]+v[i](c[i]≥c[i−1])f[i−1][1]+v[i](c[i]≥a[i−1])
最后的答案就是
m
i
n
(
f
[
n
]
[
0
]
,
f
[
n
]
[
1
]
)
min(f[n][0],f[n][1])
min(f[n][0],f[n][1])
还有就是翻转函数,真的好用,直接对string类型进行翻转。
string s;
reverse(s.begin(),s.end());
注意了,开 l o n g l o n g ! ! ! longlong!!! longlong!!!
代码还需要看吗?
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+20;
ll f[N][3],ans,a[N],inf=1e16;
string c[N],b[N],s;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
memset(f,0x3f,sizeof f);
for(int i=1;i<=n;i++)
{
cin>>s;
b[i]=s;
reverse(s.begin(),s.end());
c[i]=s;
}
f[0][0]=0;
for(int i=1;i<=n;i++)
{
if(b[i]>=b[i-1])
f[i][0]=min(f[i][0],f[i-1][0]);
if(b[i]>=c[i-1])
f[i][0]=min(f[i][0],f[i-1][1]);
if(c[i]>=b[i-1])
f[i][1]=min(f[i][1],f[i-1][0]+a[i]);
if(c[i]>=c[i-1])
f[i][1]=min(f[i][1],f[i-1][1]+a[i]);
}
ans=min(f[n][0],f[n][1]);
if(ans>=4557430888798830399) cout<<-1;
else cout<<ans;
return 0;
}