10.12 新一波高能胡策题 贪心+状压DP+分块+魔性DP

2023-12-11 15:40

本文主要是介绍10.12 新一波高能胡策题 贪心+状压DP+分块+魔性DP,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 出题人
  • Problem 1 零花钱
    • 题目来源
    • 题目描述
    • 题解
    • 代码
  • Problem 2 Oh My King
    • 题目来源
    • 题目描述
    • 题解
    • 代码
  • Problem 3 函数求和
    • 题目来源
    • 题目描述
  • Problem 4 防 AK 好题
    • 题目来源
    • 题目描述

出题人

(排名为字典序)
Chairman http://blog.csdn.net/qq_36693514
LXT http://blog.csdn.net/loi_lxtt
qrc 不用csdn的大佬
wyh 不用csdn的大佬

这里写图片描述

Problem 1 零花钱

题目来源:

http://www.tyvj.cn/p/1032
https://www.luogu.org/problem/show?pid=2376#sub
https://www.luogu.org/problem/show?pid=2619#sub

题目描述

快 NOIP 了, 国王决定开始每个星期给公主一点零花钱。
国王有一些硬币,一共有 N 种不同的面额。 国王想用给定的硬币的集合,每个星期至少给它某个零花钱的数目 C。请帮国王计算公主最多能支付多少个星期的零花钱。
每一个较小面额的硬币的面额, 都能被 比它面额更大的硬币的面额给整除

输入描述
第 1 行:两个有空格隔开的整数: N 和 C;
第 2 到第 N+1 行:每一行有两个整数表示一个面额的硬币:硬币面额 V
(1 <= V <= 100,000,000)拥有的该面额的硬币数 B (1 <= B <= 1,000,000)。

输出描述
一个单独的整数,表示最多能给支付多少个星期至少为 C 的零用钱。

样例输入
3 6
10 1
1 100
5 120

样例输出
111

数据范围及提示
题目保证给出的面额不重复;
对于 100% 的数据:
1<=N<=20 1<=C<=100000000 1<=Bi<=1000000 1<=Vi<=100000000

题解:

贪心
至少给C元,很显然的是,如果某个硬币的金额大于C,那么直接给,ans+
为了满足更多星期,我们优先使用大的面额且使花的冤枉钱最少;
按照面额大小排序,对于当前面额,在小于等于C的情况下,能放多少就放多少。
某时刻等于C则退出,进行下一次操作。
for循环结束后,如果仍然不能等于C,也就是说,如果要满足,必须大于C,那么为了花费的冤枉钱最少,我们找一个最小值加上。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,c,ans,x,y,tot,minn,tmp;
struct wkw{int v,m;
}a[800];
bool cmp(wkw a,wkw b){return a.v>b.v;
}
int main(){//freopen("money.in","r",stdin);
//  freopen("money.out","w",stdout);scanf("%d%d",&n,&c);for(int i=1;i<=n;i++){scanf("%d%d",&x,&y);if(x>=c) {ans+=y;continue;}a[++tot].v=x,a[tot].m=y;}sort(a+1,a+tot+1,cmp);while(1){tmp=c;for(int i=1;i<=tot;i++){if(a[i].m==0) continue;int maxx=min(a[i].m,tmp/a[i].v);a[i].m-=maxx;tmp-=(maxx*a[i].v);if(a[i].m) minn=i;if(tmp==0){ans++;break;}}if(tmp>0){tmp-=a[minn].v;a[minn].m--;if(tmp<=0) ans++;}if(tmp==c) break;}printf("%d",ans);return 0;
}

Problem 2 Oh! My King!

题目来源

http://www.lydsy.com/JudgeOnline/problem.php?id=1087

题目描述

很久很久以前,巨龙未曾出现, 国王风流倜傥京城酒吧鸡王南梦华【雾】 很无聊,他看过叛逆的鲁路修之后感觉国际象棋很好玩, 因此他准备搞一波国际象棋玩耍赛。由于他是国王, 他决定将棋子全换成国王来玩, 并且还是由于 EX 级皇帝特权, 所以他的国王棋子多的一笔,因此他决定在 N×N 的棋盘里面放 K个国王,使他们互不攻击。 又由于他是个乖巧的国王, 是要遵守游戏规则的, 最后他想求共有多少种摆放方案。
游戏规则: 国王能攻击到它上下左右,以及左上、 左下、 右上、 右下八
个方向上附近的各一个格子,共 8 个格子, 要保证国王互不攻击, 如果
没有方案数则输出 0。
国王鸡王南梦华听说你很厉害,决定丢你棋子钦定你干活 23333

输入描述
一行,输入 N 和 K, 意义见上文

输出描述
方案数

样例输入
3 2

样例输出
16

数据范围及提示
对于特殊的 10%的数据, n=1;
对于另 30% 的数据, 1<=n<=3, 1<=k<=n;
对于 100% 的数据,满足 1<= n<=9, 1<= k<=n*n;

题解:

讲了以后就会发现是一道很水的状压DP23333;
和炮兵阵地一样,以行为枚举单位,
预处理出每一行的状态和上下行状态是否合法(对角线上用左移右移即可);
设dp[i][j][pos]为第i行,放了j个国王,状态为pos的方案数
又上一行转移而来
答案是dp[n][k][pos] pos枚举的和(因为最后一行随便什么状态都可以)

没开long long没去文件输入输出流在bzoj上wa了几次。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
bool mmp[600][600];
int sta[600],cnt[600];
long long n,k,maxx,tot;
long long  dp[15][100][600];
int find(int x){int ans=0;while(x){if(x&1) ans++;x>>=1;}return ans;
}
void init(){int g=(1<<n);while(g){g--;if(g<<1&g) continue;sta[++tot]=g;cnt[tot]=find(g);}for(int i=1;i<=tot;i++){for(int j=1;j<=tot;j++){mmp[i][j]=mmp[j][i]=((sta[i]&sta[j])|(sta[i]>>1&sta[j])|(sta[i]<<1&sta[j]));}}
}
int main(){scanf("%lld%lld",&n,&k);init();for(int i=1;i<=tot;i++) dp[1][cnt[i]][i]=1;for(int i=2;i<=n;i++){for(int pos=1;pos<=tot;pos++){for(int j=cnt[pos];j<=k;j++){for(int p=1;p<=tot;p++){if(mmp[p][pos]) continue;dp[i][j][pos]+=dp[i-1][j-cnt[pos]][p];}}}}for(int i=1;i<=tot;i++) maxx+=dp[n][k][i];printf("%lld",maxx);return 0;
}

Problem 3 函数求和

题目来源

据说是原创题

题目描述

有一个含有 n 个数字的序列 A, 元素标号 1 到 n。
同时你有 n 个函数,标号为 1 到 n。
第 i 个函数函数值为序列中下标为 Li 到 Ri 的元素和。
现在你需要维护以下两种操作
1 x y : 将序列中下标为 x 的元素修改为 y
2 s t : 询问标号为 s 到 t 的函数值的和

输入描述
第一行一个正整数 n,表示序列和函数的个数。
接下来一行 n 个整数表示序列 A。
接下来 n 行,每行两个整数 Li, Ri,表示第 i 个函数
接下来一行一个整数 q,表示询问次数
下面 q 行,每行一个询问,格式如题面描述

输出描述
对于每个询问 2, 输出对应答案

样例输入
5
1 2 3 4 5
1 3
2 5
4 5
3 5
1 2
4
2 1 4
1 3 7
2 1 4
2 3 5

样例输出
41
53
28

数据范围及提示
对于 20%的数据, n<=100&&q<=100
对于另外 30%数据, Ri–Li<=10,所有 x 各不相同
对于 100%的数据, 1 <=n<=1e5,1<=Li<=Ri<=n, 1<=x<=n,
1<=s<=t<=n,1<=Ai,y<=1e9,1<=q<=1e5;

Problem 4 防 AK 好题

题目来源

bzoj 1017

题目描述

在你的世界中,每个人都有一个能力值, 并且初始为 0
通过金币购买装备,可以提高这一属性,并且不同装备增加的属性值不

装备分基础装备和高级装备,基础装备可以直接购买,高级装备需要基础装备合成。 合成高级装备只需要基础装备,不需要附加条件。
一件高级装备可能需要多件不同的基础装备合成,比如 A 的合成可能需要 2 * a && 3 * b && 1 * c。合成高级装备的同时,基础装备消失。
每件基础装备都有一个购买限制以为着你不能无限的购买和合成。
现在你有 m 个金币,你想知道用这些金币最大可以获得多少能力值。

输入描述
第一行两个数字 n, m 分别表示装备种类和金币数
接下来 n 行,按照装备 1 到 n 排序,每行描述一件装备。每行第一个数
字表示这件装备的力量值,接下来一个字符 A || B 表示高级装备||基础
装备。如果是基础装备,接下来两个整数表示单价和数量限制,如果是
高级装备后面一个数字 c 表示这件高级装备需要 c 种低级装备,后面的
2 c 个数分别表示这 c 件装备的种类和需求量。

输出描述
一行一个数字表示能达到的最大能力值

样例输入
10 59
5 A 3 6 1 9 2 10 1
1 B 5 3
1 B 4 3
1 B 2 3
8 A 3 2 1 3 1 7 1
1 B 5 3
5 B 3 3
15 A 3 1 1 5 1 4 1
1 B 3 5
1 B 4 3

样例输出
33

数据范围及提示
对于 100%的数据, N (1 <= n <= 51) m (0 <= m <= 2,000)
对于第 9 测试点时限为 11s, 十个点总时限为 30s

这篇关于10.12 新一波高能胡策题 贪心+状压DP+分块+魔性DP的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/481204

相关文章

上海邀请赛 A题目 HDU 5236(dp)

先求出没有ctrl+s的时候构造长度为i的期望f[i] 。然后枚举保存的次数,求出最小即可。 #include<cstdio>#include<cstdio>#include<cmath>#include<queue>#include<stack>#include<string>#include<cstring>#include<iostream>#include<map>

poj 3160 Father Christmas flymouse 强连通+dp

首先我们可以确定的是,对于val值小于0的节点都变成0.   假设一个集合内2个房间都能任意到达,那么我就可以吧集合内的所有点的价值都取到,并且可以达到任一点。实际上集合内的每个点是相同的,这样的集合就是一个强连通分量。 那么我们就可以用tarjin算法进行强连通缩点, 最后形成一个dag的图。在dag的图上面进行dp。可以先用拓扑排序后dp。或者建反响边记忆化搜索 。 VIEW

秋招突击——6/22——复习{区间DP——加分二叉树,背包问题——买书}——新作{移除元素、实现strStr()}

文章目录 引言复习区间DP——加分二叉树个人实现 背包问题——买书个人实现参考实现 新作移除元素个人实现参考思路 找出字符串中第一个匹配项的下标个人实现参考实现 总结 引言 今天做了一个噩梦,然后流了一身汗,然后没起来,九点多才起床背书。十点钟才开始把昨天那道题题目过一遍,然后十一点才开始复习题目,为了不耽误下午的时间,所以这里的就单纯做已经做过的题目,主打一个有量,不在学

动态规划DP--斐波那契数、爬楼梯、使用最小花费爬楼梯等示例代码

动态规划DP 文章目录 动态规划DP509. 斐波那契数70. 爬楼梯746. 使用最小花费爬楼梯62. 不同路径63. 不同路径II343.整数拆分 509. 斐波那契数 509. 斐波那契数 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) = 0,F(1) =

贪心推公式——AcWing 125. 耍杂技的牛

贪心推公式 定义 贪心算法是一种在每一步选择中都采取在当前状态下最优的选择,希望通过局部的最优选择来得到全局最优解的算法策略。 运用情况 问题具有最优子结构,即一个问题的最优解包含其子问题的最优解。可以通过局部最优决策逐步推导到全局最优。问题的选择策略相对明确且易于计算。 注意事项 贪心算法并不总是能得到全局最优解,可能会陷入局部最优。对于一些复杂问题,需要谨慎验证其正确性。可能需要对

洛谷 P10584 [蓝桥杯 2024 国 A] 数学题(整除分块+杜教筛)

题目 思路来源 登录 - Luogu Spilopelia 题解 参考了两篇洛谷题解,第一篇能得出这个式子,第二篇有比较严格的复杂度分析 结合去年蓝桥杯洛谷P9238,基本就能得出这题的正确做法 代码 #include<bits/stdc++.h>#include<iostream>#include<cstdio>#include<map>#include<uno

状态压缩DP——AcWing 291. 蒙德里安的梦想

状态压缩DP 定义 状态压缩DP是一种利用二进制数来表示状态的动态规划算法。它通过将状态压缩成一个整数,从而减少状态数量,提高算法效率。 运用情况 状态压缩DP通常用于解决具有状态转移和最优解性质的问题,例如组合优化、图论、游戏等问题。它的基本思想是将问题的状态表示为一个二进制数,其中每一位表示一个元素或一个状态。通过对二进制数的位运算,可以方便地进行状态转移和最优解的计算。 注意事项

LaTeX中添加矩阵分块虚线并设置虚线疏密

对于大型矩阵,有时需要添加分块虚线。 方法为使用arydshln宏包,然后在array环境中设置虚线。需要注意的是,使用矩阵环境需要搭配amsmath宏包使用,且需放在amsmath宏包之后。即导言区设置为 \usepackage{amsmath}\usepackage{arydshln} % 导入arydshln包 给出示例 \[\begin{bmatrix}\begin{array

代码随想录第31天|贪心算法

134. 加油站 参考 思路: 以每个油站相差作为判断, 比如: gas [5 8 2 8]cost [6 5 6 6] [-1 3 -4 2] 错误 : 把相差最大点当作起点判断能否绕一圈 : 相加数组是否小于0局部最优: 当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行全局最优: 找到可以跑一圈的起始位置 class

贪心算法—

贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。这种算法并不总是能找到全局最优解,但在某些问题上能提供足够好的解决方案。贪心算法的关键特性包括: 局部最优选择:在每一步决策时,都选择当前看来最佳的解决方案,不考虑长远的影响。无后效性:过去做出的选择不会影响未来的选择,也就是说,当前的最优选择不会因为之前做了