设
d
p
(
i
,
0
)
dp(i,0)
dp(i,0) 表示第 i 个人单独买票,
d
p
(
i
,
1
)
dp(i,1)
dp(i,1) 表示第 i 个人与前面的那个人一起买票。
故有转移方程
d
p
(
i
,
0
)
=
m
i
n
(
d
p
(
i
−
1
,
0
)
,
d
p
(
i
−
1
,
1
)
)
+
s
(
i
)
dp(i,0) = min(dp(i-1,0),dp(i-1,1)) + s(i)
dp(i,0)=min(dp(i−1,0),dp(i−1,1))+s(i)
d
p
(
i
,
1
)
=
m
i
n
(
d
p
(
i
−
2
,
0
)
,
d
p
(
i
−
2
,
1
)
)
+
d
(
i
−
1
)
dp(i,1) = min(dp(i-2,0),dp(i-2,1)) + d(i-1)
dp(i,1)=min(dp(i−2,0),dp(i−2,1))+d(i−1)
注意边界问题
一维也可以做
d
p
(
i
)
dp(i)
dp(i) 表示 以i结尾时的最小值。
d
p
(
i
)
=
m
i
n
(
d
p
(
i
−
2
)
+
d
(
i
−
1
)
,
d
p
(
i
−
1
)
+
s
(
i
)
)
dp(i) = min(dp(i-2) + d(i-1),dp(i-1) + s(i))
dp(i)=min(dp(i−2)+d(i−1),dp(i−1)+s(i))
表示 当前这个人自己买票或者和前面那个人一起买票
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
using namespace std;
const int N = 2e3 + 10;
const int mod = 998244353;
//#define int long long
typedef long long ll;
int dp[N][2];
int s[N],d[N];
void change(int x) {
int h = x / 3600 + 8;
x %= 3600;
int m = x / 60;
x %= 60;
int s = x;
string ss = "am";
if(h > 12) h -= 12;
if(h >= 12) ss = "pm";
printf("%02d:%02d:%02d ",h,m,s);
cout<<ss<<endl;
}
signed main(){
int tt; cin>>tt;
while(tt --) {
int n; cin>>n;
for(int i=1;i<=n;i++) cin>>s[i];
for(int i=1;i<n;i++) cin>>d[i];
memset(dp,0x3f,sizeof(dp));
dp[0][0] = dp[0][1] = 0;
for(int i=1;i<=n;i++) {
dp[i][0] = min(dp[i-1][0],dp[i-1][1]) + s[i];
if(i > 1) dp[i][1] = d[i-1];
if(i >= 2) dp[i][1] += min(dp[i-2][0],dp[i-2][1]);
}
change(min(dp[n][0],dp[n][1]));
}
return 0;
}
一维
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
using namespace std;
const int N = 2e3 + 10;
const int mod = 998244353;
//#define int long long
typedef long long ll;
int dp[N];
int s[N],d[N];
void change(int x) {
int h = x / 3600 + 8;
x %= 3600;
int m = x / 60;
x %= 60;
int s = x;
string ss = "am";
if(h > 12) h -= 12;
if(h >= 12) ss = "pm";
printf("%02d:%02d:%02d ",h,m,s);
cout<<ss<<endl;
}
signed main(){
int tt; cin>>tt;
while(tt --) {
int n; cin>>n;
for(int i=1;i<=n;i++) cin>>s[i];
for(int i=1;i<n;i++) cin>>d[i];
dp[1] = s[1];
dp[2] = min(s[1]+s[2],d[1]);
for(int i=3;i<=n;i++) dp[i] = min(dp[i-1] + s[i],dp[i-2] + d[i-1]);
change(dp[n]);
}
return 0;
}