首页 > 其他分享 >题解 - Birds

题解 - Birds

时间:2024-11-23 19:23:51浏览次数:9  
标签:召唤 魔力 limits 题解 times max Birds define

题目

题目大意

一条直线上有 \(n\) 棵树,第 \(i\) 棵树上有 \(c_i\)​ 只鸟。

在第 \(i\) 棵树下召唤一只鸟的魔力代价是 \(cost_i\)​。每召唤一只鸟,魔力上限会增加 \(B\)。每向前走一棵树,会增加 \(X\) 的魔力。一开始的魔力和魔力上限都是 \(W\)。你只能向前移动。

问最多能够召唤几只鸟。

思路简析

还是先考虑状态:必然不能以魔力为状态,那么只能以树和鸟:\(f_{i, j}\) 代表在第 \(i\) 棵树时已召唤了 \(j\) 只鸟时能有的最大魔力值。

转移方程:

\[f_{i, j} = \max\limits_{0 \leq k \leq \min\{j, c_i\}}\{f_{i-1, j-k}+X-cost_i\times k\} \]

(\(Range: i_{1\rightarrow n}, j_{0\rightarrow\sum\limits_{p=0}^i c_p}\) )

这里的 \(k\) 表示在第 \(i\) 棵树下召唤了 \(k\) 只鸟;加上的 \(X\) 是从第 \(i-1\) 棵树走到第 \(i\) 棵树的魔力值;转入该方程应有条件:$f_{i-1, j-k}-cost_i\times k$(这里不加 \(X\) 是因为)。

边界条件是 \(f_{0, 0} = W\)。

最终结果是 \(\max\limits_{f_{n, j}\ is\ existent}\{j\}\)。

那么就比较简单了。

这真的是背包 dp 吗?

另外考虑你的魔力上限,显然是 \(W+B\times j\)。

我是真服了,\(cst_i \times k\) 会爆 int,硬控我 4h+。

完了到最后好像是被盾了。

这东西虽然是三层循环,但是似乎时间复杂度仅是 \(\Omega(n\cdot\sum\limits_{i=1}^nc_i)\) 即 \(10^7\) 的(若算错请指正谢谢。)。

点击查看代码
#include <bits/stdc++.h>
#include <bits/extc++.h>
namespace {
using namespace std;
using namespace __gnu_pbds;
#define fiin(x) freopen(x".in", "r", stdin)
#define fiout(x) freopen(x".out", "w", stdout)
#define files(x) fiin(x), fiout(x)
#define und unsigned
#define ll long long
#define db double
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
#define m1p(x, y) ((x<<14)+y)
#define fir first
#define sec second
#define hap gp_hash_table
// #define pri_que 
const int man = 1e3+10, mac = 1e4+10;
}

ll n, W, B, X;
ll c[man], cst[man], sum[man];
ll f[man][mac];
int main () {
    // files("test");
    scanf("%lld%lld%lld%lld", &n, &W, &B, &X);
    for (int i = 1; i <= n; ++ i) scanf("%lld", c+i), sum[i] = sum[i-1]+c[i];
    for (int i = 1; i <= n; ++ i) scanf("%lld", cst+i);
    memset(f, -1, sizeof(f)), f[0][0] = W;

    for (int i = 1; i <= n; ++ i) 
        for (int j = 0; j <= sum[i]; ++ j) {
            for (int k = 0; k <= min(1LL*j, c[i]); ++ k) 
                if (f[i-1][j-k]-cst[i]*k>=0) 
                    f[i][j] = max(f[i][j], f[i-1][j-k]+X-cst[i]*k);
            f[i][j] = min(f[i][j], W+B*j); }

    for (int i = sum[n]; i; -- i) 
        if (f[n][i] != -1) return printf("%d", i)&0;
        
    return puts("0")&0;
}

点名批评可爱洛天依,写 \(\max\) 不写范围,中间变量还来回标错。

标签:召唤,魔力,limits,题解,times,max,Birds,define
From: https://www.cnblogs.com/stamorlin/p/18564194/CF922E

相关文章

  • 题解:CF1970E1 Trails (Easy)
    基本思路设\(dp_{i,j}\)为第\(i\)天时在第\(j\)个小屋的方案数,\(r_j\)为第\(j\)个小屋共有多少条路连接(即\(s_j+l_j\))。易得转移方程为\[dp_{i,j}=\sum_{k=1}^{m}dp_{i-1,k}\cdot(r_j\cdotr_k-l_j\cdotl_k)\](因为至少走一条短路,所以减去全长路的情况)代码实现......
  • 题解:CF644B Processing Queries
    CF644BProcessingQueries基本思路模拟题。对于每个工作申请,队列有如下两种操作:首先,将\(\leq\)当前开始时间(即\(t_i\))的所有操作弹出。接下来有两种选择:当队列已满,直接输出-1。当队列未满,更新结束时间并入队,输出新结束时间。代码实现#include<bits/stdc++.h>......
  • 题解:UVA13185 DPA Numbers I
    UVA13185DPANumbersI基本思路对于每个\(n\),枚举\(n\)的因数,最后判断因数大小即可。直接枚举到\(n-1\)有点浪费,所以可以只枚举到\(\sqrt{n}\),加上因数与\(n\)除以此因数的商。注意:最后要减去\(n\),且\(n\)为完全平方数时要减去一个\(\sqrt{n}\)。代码实现#incl......
  • 题解:SP1442 CHAIN - Strange Food Chain
    有三种可能的假话:编号\(>n\);自己吃自己;互吃。使用扩展域并查集(种类并查集)。code:#include<bits/stdc++.h>usingnamespacestd;intn,m,c,t,F[150005];intfind(intx){ if(F[x]==x)returnx; returnF[x]=find(F[x]);}intmain(){cin>>t;while......
  • 牛客小白月赛105 C,D,E题解
    题目链接:C题本来想用搜索,发现不行后还是分类讨论了,我在原来的图形上加了一圈'x'方便判断,里面的搜索可要可不要。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;lllo=1e9+7,maxx=0,l,r,t;chara[4][250500];llmod=1e9+7;lln,m,k,z,b[500050]={0};/......
  • 2024年09月CCF-GESP编程能力等级认证Scratch图形化编程一级真题解析
    本文收录于《Scratch等级认证CCF-GESP图形化真题解析》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。一、单选题(每题3分,共30分)第1题据有关资料,山东大学于1972年研制成功DJL-1计算机,并于1973年投入运行,其综合性能居当时全国第三位。DJL-1计算机运算控......
  • 洛谷P1476题解
    #include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;typedefpair<int,int>PII;constintN=110,M=210,MM=3000010;intINF=0x3f3f3f3f,mod=100003;llLNF=0x3f3f3f3f3f3f3f3f;intn,m,k,T,S,D;intg[N][N];void......
  • 读数据质量管理:数据可靠性与数据质量问题解决之道12应对与缓解
    1. 解决1.1. 当你发现数据出了故障,并且了解到它的初步影响时,下一步(有时甚至在根因分析之前)就是要解决这个问题,并且和利益相关方沟通,协商接下来该怎么做1.2. 在事故解决后,无论是通过修改代码、数据或者运行环境中的哪种方式,数据团队都应该与受到影响的各方及时沟通,并在接下来......
  • 题解 - Omkar and Password
    题目洛谷的RMJ挂了我就不挂洛谷了。题目大意给定长为\(n\)的数列,每次可以将相邻的且不相同的数字合并(即加和)。问最短能合并成几个数。思路简析虽然只是道橙题,但挺有趣。太菜了,开始被硬控5mins......
  • CRC32爆破脚本 + [MoeCTF 2022]cccrrc 题解
    CRC32爆破原理介绍:CRC(循环冗余校验)是一种用于检测数据传输错误的技术。CRC算法生成一个校验值(校验和),这个值可以附加到数据后面,在数据接收方重新计算校验值并与附加的校验值进行比较,以此来确定数据是否在传输过程中发生了错误CRC32是一种常用的CRC算法,它的校验值长度固定为3......