文章目录

敲砖块


首先把砖块向左对齐, 这样选择第

(

i

,

j

)

(i,j)

(i,j)块的前提是第

(

i

1

,

j

)

,

(

i

1

,

j

+

1

)

(i - 1, j),(i - 1,j + 1)

(i−1,j),(i−1,j+1)被选

满足敲掉的砖块总代价最大,显然是动态规划,接下来我们思考如何设计状态

按照正常的思路应当是

f

[

i

]

[

j

]

f[i][j]

f[i][j]表示到第

i

i

i行一共选择

j

j

j个的最大价值,但是选择第

i

i

i行的每一个所对应的

f

[

i

1

]

[

]

f[i-1][]

f[i−1][]的状态和选择都不一样,且很不好维护最值(貌似还要容斥)

我们尝试更改状态,思考敲掉一个砖块需要哪些被敲掉


若敲掉蓝色点

(

i

,

j

)

(i,j)

(i,j),显然第

j

j

j至少敲掉前

i

i

i个, 第

j

+

1

j + 1

j+1列至少敲掉前

i

1

i - 1

i−1个,依次类推

所以我们发现,如果按列考虑,不仅可以保证一定可以敲掉,而且统计答案非常方便

设计状态

f

[

i

]

[

j

]

[

k

]

f[i][j][k]

f[i][j][k]表示第

i

i

i列,敲掉前

j

j

j个且一共敲掉前

k

k

k的最大价值

f

[

i

]

[

j

]

[

k

]

=

m

a

x

(

f

[

i

+

1

]

[

s

]

[

k

j

]

+

s

u

m

[

j

]

[

i

]

,

s

j

1

)

f[i][j][k]= max(f[i+1][s][k-j]+sum[j][i],s\ge j-1)

f[i][j][k]=max(f[i+1][s][k−j]+sum[j][i],s≥j−1),

s

u

m

[

j

]

[

i

]

sum[j][i]

sum[j][i]表示第j列取前

i

i

i个的价值

复杂度为

n

5

n^5

n5,但是跑不满,应该除以一个至少为4的常数,所以能跑过,不过枚举

s

s

s可以优化掉,这样就变成

n

4

n^4

n4

#include<bits/stdc++.h> //竖着看
using namespace std;
#define LL long long
const int MAX = 55;
int f[MAX][MAX][MAX * MAX]; //先i列,第i列选j个,总数为 k
int n, m, a[MAX][MAX], Num[MAX];
int sum[MAX][MAX], ans = 0;
int main() {
freopen("brike.in","r",stdin);
freopen("brike.out","w",stdout);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= (n - i + 1); j++) {
scanf("%d", &a[i][j]);
sum[i][j] = sum[i - 1][j];
sum[i][j] += a[i][j];
}
for(int i = 1; i <= n; i++) Num[i] = Num[i - 1] + i;
for(int i = n; i >= 1; i--) { //第i列
for(int j = 0; j <= (n - i + 1); j++) { //第i列选j个
for(int k = Num[j]; k <= m; k++) { //选择总数
for(int s = j - 1; s <= ((n - i)); s++) { //上一列选多少
if(j == 0) { f[i][j][k] = max(f[i + 1][max(0, s)][k], f[i][j][k]); }
else if(k - j >= 0) f[i][j][k] = max(f[i][j][k], f[i + 1][s][k - j] + sum[j][i]);
ans = max(ans, f[i][j][k]);
}
}
}
}
cout<<ans<<endl;
return 0;
}

Circle


这道题难的就是问题转化

如果一个序列为

101001100

101001100

101001100,我们发现答案就是由

0

0

0隔开的连续

1

1

1的周期的

l

c

m

lcm

lcm

那么一段连续

1

1

1的方格的周期是多少,手玩可得

c

n

t

+

3

cnt+3

cnt+3,

c

n

t

cnt

cnt为连续

1

1

1的个数

那么问题就转化为了

c

n

t

i

<

=

150

\sum cnt_i<=150

∑cnti​<=150,

l

c

m

(

c

n

t

1

+

3

,

c

n

t

2

+

3

,

c

n

t

3

+

3...

)

lcm(cnt_1+3,cnt_2+3,cnt_3+3...)

lcm(cnt1​+3,cnt2​+3,cnt3​+3...)的个数

设计状态

f

[

i

]

f[i]

f[i]表示前

i

i

i个位置的

l

c

m

lcm

lcm个数,且

i

i

i个位置一定放

1

1

1

发现,

l

c

m

(

c

n

t

)

lcm(cnt)

lcm(cnt)最大也不会爆

L

L

LL

LL,最大的为选择5个30左右的质数相乘

考虑用

s

e

t

set

set转移,

f

[

i

]

f[i]

f[i]表示前

i

i

i个位置且第

i

i

i个位置一定放

1

1

1的

l

c

m

lcm

lcm种类

那么考虑第

i

i

i个位置会向前填充多少

j

j

j个连续的

1

1

1,为保证状态的合法,

f

[

i

]

f[i]

f[i]应由

f

[

j

1

]

f[j-1]

f[j−1]转移而来,保证

i

i

i向前的是单独的一段,解释起来太麻烦了,直接看代码

	f[0].insert(1);//初始化
f[1].insert(1);
for(int i = 2; i <= 150; i++) {
for(int j = i - 2; j >= 0; j--) { //保证是单独的一段
for(auto k : f[j]) {
LL lcmnow = (1LL * k * (i - j + 2) / __gcd(k, 1LL * (i - j + 2)));
f[i].insert(lcmnow);
}
}
}
for(int i = 1; i <= 150; i++) {
printf("%d ,\n", f[i].size()); //size即为答案
for(auto y : f[i]) {
f[i + 1].insert(y);//后面可以不填,对i个位置,f[i-1],f[i-2],f[i-3]..的答案也是合法的,类似前缀搞一下
}
}

做完发现时间复杂度偏高,但是150非常小,直接打表即可

//问题转化, 转方格的周期 == lcm(ai + 3)的个数
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int MAX = 160;
unordered_set<LL> f[MAX];
int ans[151] = {
0,
1 ,
2 ,
3 ,
4 ,
6 ,
8 ,
11 ,
13 ,
18 ,
21 ,
26 ,
31 ,
37 ,
45 ,
51 ,
58 ,
66 ,
78 ,
88 ,
100 ,
114 ,
128 ,
145 ,
163 ,
180 ,
200 ,
222 ,
245 ,
274 ,
305 ,
333 ,
367 ,
402 ,
443 ,
486 ,
529 ,
574 ,
629 ,
686 ,
741 ,
807 ,
872 ,
939 ,
1016 ,
1100 ,
1184 ,
1277 ,
1371 ,
1476 ,
1593 ,
1708 ,
1826 ,
1962 ,
2100 ,
2246 ,
2408 ,
2571 ,
2745 ,
2939 ,
3129 ,
3331 ,
3556 ,
3780 ,
4018 ,
4279 ,
4547 ,
4826 ,
5129 ,
5440 ,
5773 ,
6127 ,
6477 ,
6861 ,
7279 ,
7693 ,
8134 ,
8610 ,
9092 ,
9606 ,
10160 ,
10709 ,
11296 ,
11926 ,
12563 ,
13252 ,
13979 ,
14704 ,
15480 ,
16306 ,
17148 ,
18043 ,
18975 ,
19920 ,
20950 ,
22031 ,
23112 ,
24270 ,
25492 ,
26718 ,
28038 ,
29424 ,
30815 ,
32303 ,
33862 ,
35451 ,
37152 ,
38906 ,
40686 ,
42602 ,
44597 ,
46612 ,
48765 ,
50991 ,
53269 ,
55715 ,
58222 ,
60770 ,
63504 ,
66323 ,
69185 ,
72257 ,
75410 ,
78619 ,
82047 ,
85591 ,
89214 ,
93045 ,
96967 ,
101005 ,
105318 ,
109711 ,
114201 ,
118995 ,
123890 ,
128930 ,
134279 ,
139725 ,
145307 ,
151253 ,
157314 ,
163550 ,
170152 ,
176876 ,
183799 ,
191137 ,
198616 ,
206295 ,
214387 ,
222649 ,
231205};
int main() {
freopen("circle.in","r",stdin);
freopen("circle.out","w",stdout);
int n;
while(~scanf("%d", &n)) {
printf("%d\n", ans[n]);
}
// f[0].insert(1);
// f[1].insert(1);
// for(int i = 2; i <= 150; i++) {
// for(int j = i - 2; j >= 0; j--) {
// for(auto k : f[j]) {
// LL lcmnow = (1LL * k * (i - j + 2) / __gcd(k, 1LL * (i - j + 2)));
// f[i].insert(lcmnow);
// }
// }
// printf("i %d \n", i);
// }
// printf("***\n");
// for(int i = 1; i <= 150; i++) {
// printf("%d ,\n", f[i].size());
// for(auto y : f[i]) {
// f[i + 1].insert(y);
// }
// } return 0;
}

JZYZ作业好题的更多相关文章

  1. 图论期末大作业编程题(如何判断一个4连通4正则图为无爪、无K4图)

    博士期间估计这可能是唯一一个要编程的作业,搞了半天弄出这个东西,放这里为以后用到的时候查找方便. 说来也是可笑,读博士期间发现大家对上课也都没什么兴趣,老师也是那么回事,都说博士期间学的课程是要有助于 ...

  2. 16级第二周寒假作业H题

    快速幂(三) TimeLimit:2000MS  MemoryLimit:128MB 64-bit integer IO format:%I64d Problem Description 计算( AB ...

  3. c++作业22题

    一.单选题(共22题,100.0分) 1 已知int i=5,下列do-while循环语句的循环次数是 do{ cout<<i - -<<endl; i - -; }while ...

  4. 16级第一周寒假作业F题

    Subsequence TimeLimit:1000MS  MemoryLimit:65536K 64-bit integer IO format:%lld Problem Description A ...

  5. 16级第二周寒假作业E题

    Home_W的位运算4 TimeLimit:2000MS  MemoryLimit:128MB 64-bit integer IO format:%I64d Problem Description 给 ...

  6. 第二次作业 编程题 PAT 1001A+B Format

    Github的object-oriented仓库:1001.A+BFormat(20) 1.解题的思路过程 在之前学习C语言时曾经碰到过类似的将数字转换成字符输出的情况,这道题目要求输出的数字每三个间 ...

  7. Mysql综合练习作业50题

    #作业库create database db8 charset utf8; #年级表create table class_grade(gid int not null primary key auto ...

  8. 福建工程学院16级第一周寒假作业E题----第七集,奇思妙想

    第七集,奇思妙想                                                                                            ...

  9. Java第三次作业第二题

    2. [请复制本程序,作为java程序代码,进行编译,补充填写缺失代码部分,并实现题目要求功能,从而获得空白填写所需的内容.] 定义3个线程,模拟红绿灯的效果 一个线程控制画一个实心红圆 一个线程控制 ...

  10. Java第三次作业第一题

    1.[请复制本程序,作为java程序代码,进行编译,补充填写缺失代码部分,并实现题目要求功能,从而获得空白填写所需的内容.] 编写无限计时程序,从0:1开始计时,一直循环计时,计时到60秒,变为1:0 ...

随机推荐

  1. Python爬虫实战之提高CSDN访问量

    python爬虫之建立代理池(一)_CodingInCV的博客-CSDN博客 python爬虫之建立代理池(二)_CodingInCV的博客-CSDN博客 前面2篇分别介绍了从2个免费代理网站爬取免费 ...

  2. 智能制造之路—从0开始打造一套轻量级MOM平台之基础平台搭建(Linux部署)

    一.前言 前面我们选定了Admin.net来搭建我们的MOM快速开发平台,本章主要描述.NET6平台的Linux部署,以及记录搭建过程中坑. 本次搭建我们选择某云的轻量应用服务器,系统选择CentOS ...

  3. [自然语言处理] 自然语言处理库spaCy使用指北

    spaCy是一个基于Python编写的开源自然语言处理库.基于自然处理领域的最新研究,spaCy提供了一系列高效且易用的工具,用于文本预处理.文本解析.命名实体识别.词性标注.句法分析和文本分类等任务 ...

  4. maxwell数据抓取工具

    前言 maxwell是一款开源MySQL数据抓取工具,可以读取MySQL的binlog,然后转换成json并输出到kafka.redis等消息队列中. bin/maxwell,用于增量抓取 bin/m ...

  5. AT_agc064_a题解

    题面 题目大意 给定一个正整数 \(N\),要求构造一个序列.对于每一个在 \(1\) 到 \(N\) 之间的整数 \(i\),序列中包含了 \(i\) 个,并且将该序列首尾相接拼成环后,相邻两项之差 ...

  6. c++算法之离散化例题

    离散化基础2 题目描述 给定 n 个元素的数列,将相同的数据离散化为一个数据(去重),即把 {4000,201,11,45,11}{4000,201,11,45,11} 离散化为 {4,3,1,2,1 ...

  7. 强化学习 Proximal Policy Optimization (PPO)

    参考: 李宏毅老师课件 PPO = Policy Gradient 从 On-policy 到 Off-policy, 再加一些constraint Policy Gradient Basic Con ...

  8. 《CTFshow-Web入门》04. Web 31~40

    @ 目录 web31 题解 原理 web32 题解 原理 web33 题解 web34 题解 web35 题解 web36 题解 web37 题解 原理 web38 题解 原理 web39 题解 we ...

  9. python 面试题第一弹

    1. 如何理解Python中的深浅拷贝 浅拷贝(Shallow Copy)创建一个新的对象,该对象的内容是原始对象的引用.这意味着新对象与原始对象共享相同的内存地址,因此对于可变对象来说,如果修改了其 ...

  10. LeetCode46全排列(回溯入门)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 题目描述 难度:中等 给定一个不含重复数字的数组 nu ...