zoukankan      html  css  js  c++  java
  • [AH2017/HNOI2017]大佬(动态规划 搜索)

    /*
    神仙yyb
    
    理解题意可以发现  能够对大佬造成的伤害只和你怼了多少天大佬有关, 而且显然天数越多越好
    
    那么我们可以先通过预处理来找出我们最多能够怼多少天大佬 
    
    然后我们发现最后我们能怼的血量状态数是不多的??, 可以直接bfs弄一下
    这样的话我们处理出了所有的对(d, hp)表示可以使用d天打hp血量
    
    然后暴力的话就是枚举第一次怼了多少天, 第二次怼了多少天, 然后可以双指针扫一下 这样复杂度是 N * 状态数的
    
    假设我们找到的两种情况分别是 (d1, hp1), (d2, hp2) 那么需要满足等式hp1 + hp2 <= C    和 hp1 + hp2 + (D - d1 - d2) >= C才可行
    
    我们对于所有的状态按照hp排序, 然后从大到小枚举(hpi, di), 那么我们要找到的就是hpj <= C - hpi 且 dj <=  D - di 且
    hpi + hpj + (D - di - dj) >= C 的点是否存在, 然后发现第二个限制没有用
    
    那么我们就可以维护前缀的hpj - dj的最大值进行判断了
    
    只怼一次或者一次也不怼的情况可以直接判断 
    
    我怀疑这个题目是个假题, 因为样例中间一定会死??
     
    */
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #define ll long long 
    #define M 110
    #define mmp make_pair
    #include<set>
    using namespace std;
    int read()
    {
    	int nm = 0, f = 1;
    	char c = getchar();
    	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    	for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
    	return nm * f;
    }
    int n, m, maxx, tot, cnt; 
    int f[M][M], a[M], w[M];
    //int f[2][M][M], a[M], w[M];
    int sum[10001000];
    struct Note
    {
    	int hp, d;
    	bool operator < (const Note &b) const
    	{
    		return this->hp < b.hp;
    	}
    }note[10001000];
    struct Que
    {
    	int ko, cost, l;
    };
    const int inf = 100000000;
    set<ll>st;
    set<ll>::iterator it;
    
    bool find(ll x)
    {
    	it = st.find(x);
    	if(it != st.end()) return true;
    	st.insert(x);
    	return false;
    }
    
    ll ha(int hp, int d)
    {
    	return 1ll * d * 10 * inf + hp;
    }
    
    void bfs()
    {
    	queue<Que> q;
    	q.push((Que) {1, 1, 0} );
    	while(!q.empty())
    	{
    		Que now = q.front();
    		q.pop();
    		if(now.cost < tot)
    		{
    			q.push((Que){now.ko, now.cost + 1, now.l + 1});
    			if(now.l > 1 && 1ll * now.ko * now.l <= inf && !find(ha(now.ko * now.l, now.cost + 1)))
    			{
    				q.push((Que){now.ko * now.l, now.cost + 1, now.l});
    				note[++cnt] = (Note) {now.ko * now.l, now.cost + 1};
    			}
    		}
    	}
    }
    int workpre()
    {
    //	int now = 1, last = 0;
    //	f[now][maxx][0] = 1;
    //	for(int k = 1; k <= n; k++)
    //	{
    //		swap(now, last);
    //		memset(f[now], 0, sizeof(f[now]));
    //		for(int i = a[k]; i <= maxx; i++)
    //		{
    //			for(int j = 0; j < k; j++)
    //			{
    //				if(f[last][i][j])
    //				{
    //					 f[now][i - a[k]][j + 1] = true, f[now][min(maxx, i - a[k] + w[k])][j] = true;
    //				}
    //			}
    //		}
    //	}
    //	for(int i = n; i >= 0; i--) 
    //	{
    //		for(int j = 0; j <= maxx; j++)
    //		{
    //			if(f[now][j][i]) return i;
    //		}
    //	}
    	for(int i = 1; i <= n; i++) for(int j = a[i]; j <= maxx; j++) f[i][j - a[i]] = max(f[i - 1][j] + 1, f[i][j - a[i]]), f[i][min(j - a[i] + w[i], maxx)] = max(f[i - 1][j], f[i][min(j - a[i] + w[i], maxx)]);
    	int ans = 0;
    	for(int i = 1; i <= n; i++) for(int j = 1; j <= maxx; j++) ans = max(ans, f[i][j]); 
    	return ans;
    }
    
    int main()
    {
    	n = read(), m = read(), maxx = read();
    	for(int i = 1; i <= n; i++) a[i] = read();
    	for(int i = 1; i <= n; i++) w[i] = read();
    	tot = workpre();
    	bfs();
    	sort(note + 1, note + cnt + 1);
    	sum[0] = -inf;
    	for(int i = 1; i <= cnt; i++) sum[i] = max(sum[i - 1], note[i].hp - note[i].d);
    	while(m--)
    	{
    		int c = read(), flag = 0;
    		if(c <= tot) flag = 1;
    		else
    		{
    			int lst = 1;
    			for(int i = cnt; i >= 1; i--)
    			{
    				while(lst <= cnt && note[i].hp + note[lst].hp <= c) lst++;
    				if(note[i].hp <= c && tot - note[i].d >= c - note[i].hp) flag = true;
    				if(sum[lst - 1] + note[i].hp - note[i].d >= c - tot) flag = true;
    			}
    		}
    		cout << flag << "
    ";
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    mangodb学习0.1 概念
    express 学习笔记(一)路由
    vue配置路由
    screenX, clientX, pageX
    svg的世界、视窗、视野
    window.print()打印网页(一)
    cookie基础
    BOM基础
    Java三大特征:封装 继承 多态
    面向对象
  • 原文地址:https://www.cnblogs.com/luoyibujue/p/10676425.html
Copyright © 2011-2022 走看看