Codeforces Round 934 (Div. 2) ---- counting is fun (Easy and Hard Version)

2024-03-31 01:52

本文主要是介绍Codeforces Round 934 (Div. 2) ---- counting is fun (Easy and Hard Version),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

F1. Counting Is Fun (Easy Version):

题目大意:

思路解析:

代码实现:

D2. Counting Is Fun (Hard Version):

思路解析:

代码实现:


 

F1. Counting Is Fun (Easy Version):

题目大意:

思路解析:

我们可以考虑一下,在题目条件下好数组有什么性质。 假如n=4, 那我们令好数组的四个值为 a b c d。 假如我们第一次的选择 [l,r] == [1,2],那么数组值为 1 1 0 0,或者 k k 0 0.第二次选择[l,r] ==[2,3], 那么数组值为 k k+m m 0, 可以发现如果ai增加了f, 那么 ai-1 或者 ai+1 也一定会增加 f。所以可以发现一个特殊的性质  ai <= ai-1 + ai+1。 那么我们便可以利用这个性质来进行dp了。

dp[a][b] 代表在当前 位置i下,ai==b,ai == a的情况下满足好数组的定义的数组个数有多少。那么i+1转移 dp[b][c] = dp[m][b]   (max(b-c, 0) <= m <= m ) 对m求和。 这里m的取值范围用到上诉发现的性质即可。 时间复杂度为 O(N^3)

代码实现:

import java.io.*;
import java.math.BigInteger;
import java.util.*;public class Main {static int inf = (int) 2e7;public static void main(String[] args) throws IOException {int t = f.nextInt();while (t > 0) {solve();t--;}w.flush();w.close();br.close();}public static void solve() {int n = f.nextInt(); int k = f.nextInt(); int mod = f.nextInt();int[][] dp = new int[k+1][k+1];dp[0][0] = 1;for (int i = 1; i <= n+2; i++) {int[][] ndp = new int[k+1][k+1];int[][] pre = new int[k+1][k+1];for (int b = 0; b <= k; b++) {pre[b][0] = dp[0][b];for (int a = 1; a <= k; a++) {pre[b][a] = (pre[b][a-1] + dp[a][b]) % mod;}}for (int b = 0; b < k+1; b++) {for (int c = 0; c < k + 1; c++) {if (b > c) ndp[b][c] = (pre[b][k] - pre[b][b-c-1] + mod) % mod;else ndp[b][c] = pre[b][k];}}dp = ndp;}w.println(dp[0][0]);}static PrintWriter w = new PrintWriter(new OutputStreamWriter(System.out));static Input f = new Input(System.in);static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static class Input {public BufferedReader reader;public StringTokenizer tokenizer;public Input(InputStream stream) {reader = new BufferedReader(new InputStreamReader(stream), 32768);tokenizer = null;}public String next() {while (tokenizer == null || !tokenizer.hasMoreTokens()) {try {tokenizer = new StringTokenizer(reader.readLine());} catch (IOException e) {throw new RuntimeException(e);}}return tokenizer.nextToken();}public String nextLine() {String str = null;try {str = reader.readLine();} catch (IOException e) {// TODO 自动生成的 catch 块e.printStackTrace();}return str;}public int nextInt() {return Integer.parseInt(next());}public long nextLong() {return Long.parseLong(next());}public Double nextDouble() {return Double.parseDouble(next());}public BigInteger nextBigInteger() {return new BigInteger(next());}}
}

D2. Counting Is Fun (Hard Version):

思路解析:

题目大意类似,只是把n的限制范围 调到了 n <= 3000, 根据简单版本的时间复杂度O(N^3) 是过不了的,考虑怎么进行优化,第一题我们是枚举 b 和 c 通过特殊性质来推出a的可行范围,那我们想是否可以只枚举c,然后通过容斥原理来进行转移的加速。

第一个版本的枚举 :

a1 m c:  -> a1 >=m-c  ---- 相当于 ai-2等于这些数(0 ---- m-c-1) 是无效的

a2 m-1 c: -> a2 >= m-1-c  ---- 相当于 ai-2等于这些数(0 ---- m-c-2) 是无效的

a3 m-2 c: -> a3 >= m-2-c .....  ---- 相当于 ai-2等于这些数(0 ---- m-c-3) 是无效的

那么便可以推出一个结论 :f(i,j) = f(i-1,k) - f(i-2,k) * (K - j - k) 对 k = (1,K)进行求和; 然后发现后面两个数组在 O(N)的情况下就可以使用前缀和预处理出来。

代码实现:

import java.io.*;
import java.math.BigInteger;
import java.util.*;public class Main {static int inf = (int) 2e7;public static void main(String[] args) throws IOException {int t = f.nextInt();while (t > 0) {solve();t--;}w.flush();w.close();br.close();}public static void solve() {int n = f.nextInt(); int k = f.nextInt(); int mod = f.nextInt();long[][] dp = new long[n+2][k+1];dp[0][0] = 1;for (int i = 1; i <= n + 1; i++) {long s = 0;for (int j = 0; j <= k; j++) {s += dp[i-1][j];s %= mod;}for (int j = 0; j <= k; j++) {dp[i][j] = s;}if (i >= 2){long[] g = new long[k+1];long[] h = new long[k+1];for (int j = 0; j <= k; j++) {g[j] = dp[i - 2][j];h[j] = dp[i-2][j] * j;if (j > 0){g[j] += g[j-1];h[j] += h[j-1];g[j] %= mod;h[j] %= mod;}}for (int j = 0; j <= k; j++) {long x = (g[k - j] * (k - j) - h[k - j] + mod) % mod;dp[i][j] = (dp[i][j] - x + mod) % mod;}}}w.println(dp[n+1][0]);}static PrintWriter w = new PrintWriter(new OutputStreamWriter(System.out));static Input f = new Input(System.in);static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static class Input {public BufferedReader reader;public StringTokenizer tokenizer;public Input(InputStream stream) {reader = new BufferedReader(new InputStreamReader(stream), 32768);tokenizer = null;}public String next() {while (tokenizer == null || !tokenizer.hasMoreTokens()) {try {tokenizer = new StringTokenizer(reader.readLine());} catch (IOException e) {throw new RuntimeException(e);}}return tokenizer.nextToken();}public String nextLine() {String str = null;try {str = reader.readLine();} catch (IOException e) {// TODO 自动生成的 catch 块e.printStackTrace();}return str;}public int nextInt() {return Integer.parseInt(next());}public long nextLong() {return Long.parseLong(next());}public Double nextDouble() {return Double.parseDouble(next());}public BigInteger nextBigInteger() {return new BigInteger(next());}}
}

这篇关于Codeforces Round 934 (Div. 2) ---- counting is fun (Easy and Hard Version)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

提示:Decompiled.class file,bytecode version如何解决

《提示:Decompiled.classfile,bytecodeversion如何解决》在处理Decompiled.classfile和bytecodeversion问题时,通过修改Maven配... 目录问题原因总结问题1、提示:Decompiled .class file,China编程 bytecode

[Gym103960B] Fun with Stones

并不是多困难或者有趣的题,写sol仅仅是因为觉得好笑()。 题目大意 三堆石子 Nim 游戏,第 i i i 堆石子数量在 [ l i , r i ] [l_i , r_i] [li​,ri​] 中随机,求先手必胜的概率,对 1 0 9 + 7 10^9+7 109+7 取模。 l i , r i ≤ 1 0 9 l_i , r_i≤10^9 li​,ri​≤109。 题解 说人

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

Codeforces 482B 线段树

求是否存在这样的n个数; m次操作,每次操作就是三个数 l ,r,val          a[l] & a[l+1] &......&a[r] = val 就是区间l---r上的与的值为val 。 也就是意味着区间[L , R] 每个数要执行 | val 操作  最后判断  a[l] & a[l+1] &......&a[r] 是否= val import ja

Maven创建项目中的groupId, artifactId, 和 version的意思

文章目录 groupIdartifactIdversionname groupId 定义:groupId 是 Maven 项目坐标的第一个部分,它通常表示项目的组织或公司的域名反转写法。例如,如果你为公司 example.com 开发软件,groupId 可能是 com.example。作用:groupId 被用来组织和分组相关的 Maven artifacts,这样可以避免

CSS实现DIV三角形

本文内容收集来自网络 #triangle-up {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid transparent;border-bottom: 100px solid red;} #triangle-down {width: 0;height: 0;bor

LibSVM学习(六)——easy.py和grid.py的使用

我们在“LibSVM学习(一)”中,讲到libSVM有一个tools文件夹,里面包含有四个python文件,是用来对参数优选的。其中,常用到的是easy.py和grid.py两个文件。其实,网上也有相应的说明,但很不系统,下面结合本人的经验,对使用方法做个说明。        这两个文件都要用python(可以在http://www.python.org上下载到,需要安装)和绘图工具gnup