[BZOJ4828][DP]HNOI2017:大佬(cyk)

BZOJ4828

观察发现,我们加血和攻击是两个互不影响的操作,只要保证我们时刻存活就可以进行攻击,而攻击又有一些约束条件,方便起见,我们设置三个子任务 s u b t a s k subtask subtask

  • s u b t a s k 1 : subtask1: subtask1处理出,保证自己存活的情况下,可以有多少天自由行动(不回血)
  • s u b t a s k 2 : subtask2: subtask2在完成 s u b t a s k 1 subtask1 subtask1后处理出,自由行动的时候,花多少天能够对大佬造成多少伤害,要具体到每一个可能数值上,因为只能把血打成0,这里只考虑攻击一次
  • s u b t a s k 3 : subtask3: subtask3在完成 s u b t a s k 2 subtask2 subtask2后,我们能否击败每个大佬

对于 s u b t a s k 1 subtask1 subtask1,一个简单dp即可
对于 s u b t a s k 2 subtask2 subtask2,搜索一下,map或者hash判重
对于 s u b t a s k 3 subtask3 subtask3,我们分析一下限制条件,写成不等式得到:
对 于 两 次 攻 击 ( d 1 , f 1 ) , ( d 2 , f 2 ) ( d : 天 数 , f : 嘲 讽 力 ) 对于两次攻击(d1,f1),(d2,f2) (d:天数,f:嘲讽力) (d1,f1),(d2,f2)(d:,f:)
1. c [ i ] ≥ f 1 + f 2 ( 不 能 把 血 打 成 负 数 ) 1.c[i]\geq f1+f2 (不能把血打成负数) 1.c[i]f1+f2
2. D − d 1 − d 2 ≥ c [ i ] − f 1 + f 2 ( 要 打 死 , 剩 下 的 要 通 过 顶 嘴 打 掉 , D 为 可 自 由 行 动 的 天 数 ) 2.D-d1-d2 \geq c[i]-f1+f2 (要打死,剩下的要通过顶嘴打掉,D为可自由行动的天数) 2.Dd1d2c[i]f1+f2D

把二式移项,令D单独在左边,枚举 d 1 − f 1 d1-f1 d1f1,则如果 f f f为有序,那么根据一式便满足单调性,要求 d 2 − f 2 d2-f2 d2f2的最小值就很好求了
特殊情况:如果可以直接嘴炮打死,就直接输出1
Code:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int res=0,f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
	while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
	return res*f;
}
const int N=105,INF=990000000;
struct fxxk{int day,F,L;};
map<int,int>mp[N];
pair<int,int>s[2000005];
int n,m,f[N][N],w[N],a[N],mc,D=0,c[N],lim,cnt=0;
inline void dp(){
	memset(f,128,sizeof(f));f[0][mc]=0;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=mc-a[i];j++){
			f[i][min(mc,j+w[i])]=max(f[i][min(mc,j+w[i])],f[i-1][j+a[i]]);
			f[i][j]=max(f[i][j],f[i-1][j+a[i]]+1);
			D=max(D,f[i][j]);
		}
}
inline void bfs(int tot){
	queue<fxxk>q;q.push((fxxk){1,1,0});
	while(!q.empty()){
		fxxk x=q.front();q.pop();
		if(x.day<tot){
			q.push((fxxk){x.day+1,x.F,x.L+1});
			if(x.L>1 && x.F<lim/x.L && !mp[x.L][x.L*x.F]){
				fxxk y=(fxxk){x.day+1,x.F*x.L,x.L};
				mp[x.L][x.L*x.F]=1;
				s[++cnt]=make_pair(y.F,y.day);q.push(y);
			}
		}
	}
}
int main(){
	n=read();m=read();mc=read();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++) w[i]=read();
	for(int i=1;i<=m;i++) c[i]=read(),lim=max(lim,c[i]);
	dp();
	bfs(D);sort(s+1,s+cnt+1);
	for(int i=1;i<=m;i++){
		int ans=0,minn=INF;
		if(c[i]<D){puts("1");continue;}
		for(int j=cnt,k=1;j;j--){
			while(k<=cnt && s[k].first+s[j].first<=c[i]) minn=min(minn,s[k].second-s[k].first),k++;
			if(minn+c[i]-s[j].first+s[j].second<=D){ans=1;break;}
			if(s[j].first<=c[i] && s[j].second+c[i]-s[j].first<=D) {ans=1;break;}
		}
		cout<<ans<<"\n";
	}
	return 0;
}
基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值