Stay Hungry,Stay Foolish!

D - Step Up Robot

D - Step Up Robot

https://atcoder.jp/contests/abc289/tasks/abc289_d

 

思路 - 1 DFS

从0开始, 否则运用所有可能步子,检查新的位置点, 遇到block返回false, 是目标点x返回true

Code - 1 DFS

https://atcoder.jp/contests/abc289/submissions/38813788

 
int n;
vector<int> a;
int m;
vector<int> b;
int x;
 
map<int, bool> vis;
map<int, bool> cache;
 
bool dfs(int s){
    if (vis[s]){
        return cache[s];
    }
    
    if (s == x){
        vis[s] = true;
        cache[s] = true;
        return true;
    }
    
    if(s > x){
        vis[s] = true;
        cache[s] = false;
 
        return false;
    }
 
    REP(i, m){
        if(s == b[i]){
            vis[s] = true;
            cache[s] = false;
 
            return false;
        }
    }
    
    REP(i, n){
        int step = a[i];
        int next = s + step;
        
        if (dfs(next)){
            vis[s] = true;
            cache[s] = true;
 
            return true;
        }
    }
    
    vis[s] = true;
    cache[s] = false;
 
    return false;
}
 
int main()
{
    cin >> n;
    REP(i, n){
        int temp;
        cin >> temp;
        a.push_back(temp);
    }
 
    cin >> m;
    REP(i, m){
        int temp;
        cin >> temp;
        b.push_back(temp);
    }
 
    cin >> x;
 
    bool ret = dfs(0);
    
    cout << (ret?"Yes":"No") << endl;
 
    return 0;
}
 

 

思路 - 2 visited标记法

从0开始,先标记0位置为true

然后运用所有步子, 对于新的位置点,如果不是block, 则标记为true

Code - 2 visited标记法

https://atcoder.jp/contests/abc289/submissions/38820472

 
int n;
vector<int> a;
int m;
vector<int> b;
int x;
 
int vis[100050];
 
int main()
{
    cin >> n;
    REP(i, n){
        int temp;
        cin >> temp;
        a.push_back(temp);
    }
 
    cin >> m;
    REP(i, m){
        int temp;
        cin >> temp;
        b.push_back(temp);
        
        vis[temp] = -1;
    }
 
    cin >> x;
 
    vis[0] = 1;
    REP(i, x){
        int curpos = vis[i];
        if(curpos != 1){
            continue;
        }
        
        REP(j, n){
            int step = a[j];
            int next = i + step;
            if (next>100000){
                continue;
            }
            
            if (vis[next] == -1){
                continue;
            }
            
            vis[next] = 1;
        }
    }
 
    cout << (vis[x]==1?"Yes":"No") << endl;
 
    return 0;
}
 

 

思路3 - DP

从后往前运用所有步子, 判断是否可以标记为true

Code - DP

https://atcoder.jp/contests/abc289/submissions/38801536

 

#include <bits/stdc++.h>
using namespace std;
bool vis[100007];
map<int,bool>dan;
int main(){
    int n,m;
    cin>>n;
    vector<int>v(n);
    for(int i=0;i<n;i++){
        cin>>v[i];
    }
    cin>>m;
    for(int i=0;i<m;i++){
        int num;
        cin>>num;
        dan[num]=1;
    }
    int x;
    cin>>x;
    vis[0]=1;
    for(int i=1;i<=x;i++){
        if(dan[i]){
            continue;
        }
        for(int j=0;j<n;j++){
            if(v[j]>i){
                continue;
            }
            vis[i]|=vis[i-v[j]];
        }
    }
    cout<<(vis[x]?"Yes":"No")<<endl;
} 

 

posted @ 2023-02-11 22:32  lightsong  阅读(29)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel