CF1799D1 Hot Start Up (easy version) 题解
违规用户名1045961 · · 题解
没有多难(老师说这题蓝得发绿),直接 DP。
首先设
稍微思考可得转移方程(箭头左边的数与箭头右的求最小值并更新箭头左的数):\
若
转移的次序和我以前学的不一样,是枚举合法状态推出后继状态。边界:在
时间复杂度
AC Code
#include <iostream>
#define int long long
#define inf 1000000000000000000ll
using namespace std;
int n,k,a[5001],h[5001],c[5001],dp[5001][5001];
void solve() {
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=k;i++)
cin>>c[i];
for(int i=1;i<=k;i++)
cin>>h[i];
for(int i=0;i<=n;i++)
fill(dp[i],dp[i]+k+1,inf);
dp[0][0]=0;
for(int i=0;i<n;i++)
for(int j=0;j<=k;j++) if(dp[i][j]<inf) {
dp[i+1][j]=min(dp[i+1][j],dp[i][j]+(a[i+1]==a[i]?h[a[i+1]]:c[a[i+1]]));
dp[i+1][a[i]]=min(dp[i+1][a[i]],dp[i][j]+(a[i+1]==j?h[a[i+1]]:c[a[i+1]]));
}
int ans=inf;
for(int i=0;i<=k;i++)
ans=min(ans,dp[n][i]);
cout<<ans<<'\n';
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false),
cout.tie(nullptr);
signed t;
for(cin>>t;t--;solve());
return 0;
}
如果觉得这题简单可以试试这题的升级版,我们老师说这个蓝的发紫~~~