【记忆化搜索】codevs2823锁妖塔
[codevs2823]锁妖塔
Description
琐妖塔会在一会儿后倒塌。大量妖魔涌出塔去,塔内的楼梯都挤满了人(哦,错了,是妖),(那他们怎么不飞下去--)要求是,景天一行一定要下塔,琐妖塔一共N层,但是他突然大发慈悲,觉得妖怪是无辜,所以他不想踩死这些妖魔,所以他的速度最多比妖怪速度大K(否则会踩死妖怪的),并且速度不能比妖怪们慢,否则会被踩死。琐妖塔一共有N层,并且每层怪物逃跑的速度都不相同,景天每下一层,可以选择将他的速度加快一个单位或者减慢一个单位或者保持原来的速度不变。并且他下每一层的速度之和除以(N-1)要尽量大。当然跑下楼时他一定要活着。
现在景天刚拿到镇妖剑,头有点热,不能思考了,请你编个程序帮帮他吧!
提示:1楼不需要再下了,N层楼只需要下N-1层。并且在第N层楼到N-1层时必须为初始速度。
Input Description
第一行,三个整数N,V(初始速度),K(最多比其他妖快的速度值)
第二行,N-1个整数,分别代表从第二层到第N层的妖怪的速度
其中2〈=N〈=100,0〈=K〈=100,1〈=V〈=100。
Output Description
若能下楼,输出速度之和除以(N-1),保留两位小数。
若不能,那就仰天大吼一声,输出“REN JIU SHI BU NENG REN CI!”(不含引号)
Sample Input
Input1
3 3 2
2 2
Input2
3 3 0
2 2
样例输出 Sample Output
Output1
3.50
Output2
REN JIU SHI BU NENG REN CI!
试题分析:记忆化搜一下就可以了……
#include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<stack> #include<vector> #include<algorithm> //#include<cmath> using namespace std; const int INF = 9999999; #define LL long long inline int read(){ int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } int N,V,K; int a[101]; int f[101][101]; bool vis[101][101]; int ans; bool search(int n,int v){ if(vis[n][v]) return f[n][v]; vis[n][v]=true; if(n==1) return 1; if(v-a[n]>K||v<a[n]) return 0; return f[n][v]=search(n-1,v+1)||search(n-1,v)||search(n-1,v-1); } void GA(int n,int v){ if(n==1) return; ans+=v; if(f[n-1][v+1]) GA(n-1,v+1); else if(f[n-1][v]) GA(n-1,v); else GA(n-1,v-1); } int main(){ N=read(),V=read(),K=read(); for(int i=2;i<=N;i++) a[i]=read(); int p=V; for(int i=N;i>=2;i--){ if(p>K+a[i]) { cout<<"REN JIU SHI BU NENG REN CI! "; return 0; } if(p>1) p--; } search(N,V); if(!f[N][V]) cout<<"REN JIU SHI BU NENG REN CI! "; else{GA(N,V);printf("%.2lf",(double)ans/(N-1));} return 0; }
你——悟到了么?