看了N遍才看懂题意。。。
题意:给N个区间,每次能向左或向右走区间长度这么多,问能不能每次都在[0,m]这个范围内
思路:爆搜是不行的。。这里把状态记录一下能剪枝很多
定义:s[pos][now]=-1\0\1分别为“时间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\n"); else printf("impossible\n"); return 0; }
时间: 2024-12-21 18:23:52