P14508 猜数游戏 guess
qqqaaazzz_qwq · · 题解
记
目标位置在任何时刻,都一定是可能在一段区间内出现。
一开始是
还要跑个最短路,
复杂度
#include <bits/stdc++.h>
#define int long long
#define FAST ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
/*
by qqqaaazzz
dis[i] 表示造成了 i 的真实位移的代价
*/
int n,m;
int a[50010],b[50010];
int f[50010],g[50010];
int D[2010][2010];
int dis[2010];
bool vis[2010];
int is[2010];
int dp[50010];//dp[i] 表示还剩 i 个的时候呢?
void solve(){
cin >> n >> m;
for (int i=1;i<=m;i++) cin >> a[i];
for (int i=1;i<=m;i++) cin >> b[i];
memset(D,0x3f,sizeof(D));
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
for (int i=0;i<=2000;i++){
for (int j=1;j<=m;j++){
if(i+a[j]<=2000) D[i][i+a[j]] = min(D[i][i+a[j]],b[j]);
if(abs(i-a[j])<=2000) D[i][abs(i-a[j])] = min(D[i][abs(i-a[j])],b[j]);
}
}
//跑 Dij
dis[0] = 0;
for (int i=0;i<=2000;i++){
int k = -1;
for (int j=0;j<=2000;j++){
if(!vis[j]&&(k==-1||dis[j]<dis[k])) k = j;
}
vis[k] = 1;
for (int j=0;j<=2000;j++){
dis[j] = min(dis[j],dis[k]+D[k][j]);
}
}
memset(dp,0x3f,sizeof(dp));
dp[1] = 0;
for (int i=2;i<=n;i++){
for (int j=1;j<=min(i-1,2000ll);j++){
dp[i] = min(dp[i],max(dp[j],dp[i-j])+dis[j]);
}
}
cout << (dp[n]>1e18? -1:dp[n]) << "\n";
}
signed main()
{
FAST;
int c,t;
cin >> c >> t;
while(t--) solve();
return 0;
}