[ABC291F] Teleporter and Closed off - 洛谷
有 �N 个城市,编号为 1,2,…,�1,2,…,N。还有单向传送门,可以将你传送到不同的城市。一个传送门是否可以直接从城市 �i (1≤�≤�)(1≤i≤N) 传送到另一个城市,由长度为 �M 的字符串 ��Si 表示。
具体来说,对于 1≤�≤�1≤j≤N,如果 1≤�−�≤�1≤j−i≤M 并且 ��Si 的第 (�−�)(j−i) 个字符是1,则传送门可以直接从城市 �i 传送到城市 �j;否则,它不能直接从城市 �i 传送到城市 �j。对于 �=2,3,…,�−1k=2,3,…,N−1,
解决以下问题:
你能否在不经过城市 �k 的情况下从城市 11 到达城市 �N,反复使用传送门?如果可以,打印出你需要使用传送门的最小次数;否则,打印出 −1−1。
There are �N cities numbered city 11, city 22, ……, and city �N.
There are also one-way teleporters that send you to different cities. Whether a teleporter can send you directly from city �i (1≤�≤�)(1≤i≤N) to another is represented by a length-�M string ��Si consisting of 0 and 1. Specifically, for 1≤�≤�1≤j≤N,
- if 1≤�−�≤�1≤j−i≤M and the (�−�)(j−i)-th character of ��Si is
1, then a teleporter can send you directly from city �i to city �j; - otherwise, it cannot send you directly from city �i to city �j.
Solve the following problem for �=2,3,…,�−1k=2,3,…,N−1:
Can you travel from city 11 to city �N without visiting city �k by repeatedly using a teleporter? If you can, print the minimum number of times you need to use a teleporter; otherwise, print −1−1.
Constraints
- 3≤�≤1053≤N≤105
- 1≤�≤101≤M≤10
- �<�M<N
- ��Si is a string of length �M consisting of
0and1. - If �+�>�i+j>N, then the �j-th character of ��Si is
0. - �N and �M are integers.
Input
The input is given from Standard Input in the following format:
�N �M �1S1 �2S2 ⋮⋮ ��SN
Output
Print (�−2)(N−2) integers, separated by spaces, in a single line. The �i-th (1≤�≤�−2)(1≤i≤N−2) integer should be the answer to the problem for �=�+1k=i+1.
Sample 1
| Inputcopy | Outputcopy |
|---|---|
5 2 11 01 11 10 00 | 2 3 2 |
A teleporter sends you
- from city 11 to cities 22 and 33;
- from city 22 to city 44;
- from city 33 to cities 44 and 55;
- from city 44 to city 55; and
- from city 55 to nowhere.
Therefore, there are three paths to travel from city 11 to city 55:
- path 11 : city 11 →→ city 22 →→ city 44 →→ city 55;
- path 22 : city 11 →→ city 33 →→ city 44 →→ city 55; and
- path 33 : city 11 →→ city 33 →→ city 55.
Among these paths,
- two paths, path 22 and path 33, do not visit city 22. Among them, path 33 requires the minimum number of teleporter uses (twice).
- Path 11 is the only path without city 33. It requires using a teleporter three times.
- Path 33 is the only path without city 44. It requires using a teleporter twice.
Thus, 22, 33, and 22, separated by spaces, should be printed.
Sample 2
| Inputcopy | Outputcopy |
|---|---|
6 3 101 001 101 000 100 000 | -1 3 3 -1 |
The only path from city 11 to city 66 is city 11 →→ city 22 →→ city 55 →→ city 66.
For �=2,5k=2,5, there is no way to travel from city 11 to city 66 without visiting city �k.
For �=3,4k=3,4, the path above satisfies the condition; it requires using a teleporter three times.
Thus, −1−1, 33, 33, and −1−1, separated by spaces, should be printed.
Note that a teleporter is one-way; a teleporter can send you from city 33 to city 44, but not from city 44 to city 33,
so the following path, for example, is invalid: city 11 →→ city 44 →→ city 33 →→ city 66.
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+11,inf = 1e9+7;
int n,m;
string a[maxn];
int f[maxn],g[maxn];
bool check(int i,int j){
int dis = j-i;
if(j-i>m)return 0;
if(a[i][dis] == '1')return 1;
return 0;
}
int main(){
memset(f,0x3f,sizeof(f));
memset(g,0x3f,sizeof(g));
cin>>n>>m;
for(int i = 1;i <= n;i++){
cin>>a[i];
a[i] = " "+a[i];
}
f[1] = 0;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
int to = i+j;
if(a[i][j] =='1'){
f[to] = min(f[to],f[i]+1);
}
}
}
g[n] = 0;
for(int i = n;i >= 1;i--){
for(int j = 1;j <= m;j++){
int to = i-j;
if(to <= 0)continue;
if(a[to][j] =='1'){
g[to] = min(g[to],g[i]+1);
}
}
}
for (int k = 2; k <= n-1; k++) {
int ans = inf;
for (int l = max(1,k-m);l < k;l++){
for(int r = k+1;r <= min(n,k+m);r++){
if(check(l,r))ans = min(ans,f[l]+g[r]+1);
}
}
if(inf == ans)cout<<-1<<" ";
else cout<<ans<<" ";
}
return 0;
}
Hot Start Up (easy version) - 洛谷
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5010;
long long dp[maxn][maxn],a[maxn],hot[maxn],cold[maxn];
void slove(){
int n,k;
cin>>n>>k;
for(int i = 1;i <= n;i++){
cin>>a[i];
}
for(int i = 1;i <= k;i++){
cin>>cold[i];
}
for(int i = 1;i <= k;i++){
cin>>hot[i];
}
for(int i = 0;i <= n;i++){
for(int j = 0;j <= k;j++){
dp[i][j] = 1e18;
}
}
a[0] = -1;
dp[1][0] = cold[a[1]];
for(int i = 2;i <= n;i++){
int first = a[i-1];
for(int j = 0;j <= k;j++){
dp[i][j] = min(dp[i][j],dp[i-1][j]+(a[i] == first?hot[a[i]]:cold[a[i]]));
dp[i][first] = min(dp[i][first],dp[i-1][j]+(a[i] == j?hot[a[i]]:cold[a[i]]));
}
}
long long ans = 1e18;
for(int i = 0;i <= k;i++){
ans = min(ans,dp[n][i]);
}
cout<<ans<<endl;
}
int main(){
//memset(f,0x3f,sizeof(f));
int t;
cin>>t;
while(t--){
slove();
}
}
Hot Start Up (hard version) - 洛谷
#include<bits/stdc++.h>
using namespace std;
const int maxn = 305010;
long long dp[maxn],a[maxn],hot[maxn],cold[maxn];
long long sum[maxn];
void slove(){
int n,k;
cin>>n>>k;
for(int i = 1;i <= n;i++){
cin>>a[i];
}
for(int i = 1;i <= k;i++){
cin>>cold[i];
}
for(int i = 1;i <= k;i++){
cin>>hot[i];
dp[i] = 1e18;
}
dp[0] = 0;
long long s = 0,mindp = 0;
for(int i = 1;i <= n;i++){
if(a[i] == a[i-1]){
s += hot[a[i]];
}
else{
s += cold[a[i]];
dp[a[i-1]] = min(dp[a[i]]+hot[a[i]],mindp+cold[a[i]])-cold[a[i]];
mindp = min(mindp,dp[a[i-1]]);
}
}
cout<<s+mindp<<endl;
}
int main(){
//memset(f,0x3f,sizeof(f));
ios::sync_with_stdio(0);
int t;
cin>>t;
while(t--){
slove();
}
}
探讨在给定城市和单向传送门条件下,如何避免特定城市并找到从城市1到城市N的最短路径,涉及路径搜索算法。
246

被折叠的 条评论
为什么被折叠?



