zoukankan      html  css  js  c++  java
  • COJ 1686:记忆化搜索

    看了N遍才看懂题意。。。

    题意:给N个区间,每次能向左或向右走区间长度这么多,问能不能每次都在[0,m]这个范围内

    思路:爆搜是不行的。。这里把状态记录一下能剪枝很多

    定义:s[pos][now]=-11分别为“时间now走到pos这个位置是不能、没试过、能走到终点而满足要求”

    pos最大是100,now最大是1e4,开得下。然后搜一下就好了

    #include"cstdio"
    #include"queue"
    #include"cmath"
    #include"stack"
    #include"iostream"
    #include"algorithm"
    #include"cstring"
    #include"queue"
    #include"map"
    #include"set"
    #include"vector"
    #define ll long long
    #define mems(a,b) memset(a,b,sizeof(a))
    #define ls pos<<1
    #define rs pos<<1|1
    
    using namespace std;
    const int MAXN = 120;
    const int MAXM = 10050;
    const int INF = 0x3f3f3f3f;
    int n,m,flag;
    int x[MAXN];
    int s[MAXN][MAXM];
    
    int dfs(int now,int pos){
        if(pos>=n) return 1;
        if(s[pos][now]) return s[pos][now];
        if(now+x[pos]<=m&&dfs(now+x[pos],pos+1)==1) {s[pos][now]=1;return 1;}
        if(now-x[pos]>=0&&dfs(now-x[pos],pos+1)==1) {s[pos][now]=1;return 1;}
        s[pos][now]=-1;
        return -1;
    }
    
    int main(){
        //freopen("in.txt","r",stdin);
        int f;
        scanf("%d",&f);
        int ok=1;
        while(f--){
            scanf("%d%d",&m,&n);
            for(int i=0;i<n;i++){
                int a,b;
                scanf("%d%d",&a,&b);
                x[i]=b-a;
            }
            mems(s,0);
            flag=0;
            for(int i=0;i<=m;i++){
                if(dfs(i,0)==1) flag=1;
                if(flag) break;
            }
            if(!flag) ok=0;
        }
        if(ok) printf("possible
    ");
        else printf("impossible
    ");
        return 0;
    }
    View Code
  • 相关阅读:
    Ackerman 函数奇怪的函数
    HDU2871 Memory Control 线段树区间合并
    HDU3667 Hotel 线段树 经典空间合并
    图论
    HDU3016 Man Down 线段树
    HDU1878 欧拉回路 判定是否存在欧拉回路
    从今开始
    如何打开注册表编辑器
    ASP.NET中TextBox控件设置ReadOnly="true"后台取不到值
    学习笔记(2011年5月到9月)
  • 原文地址:https://www.cnblogs.com/luxiaoming/p/5264116.html
Copyright © 2011-2022 走看看