洛谷 P4749 - [CERC2017]Kitchen Knobs(差分转换+dp,思维题)
一道挺有意思的思维题。
首先有一个 obvious 的结论,就是对于每个炉子,要么转到哪里都符合条件,要么存在唯一的最大值。对于转到哪儿都符合条件的炉子我们 duck 不必考虑它,故我们只用考虑存在唯一最大值的炉子即可,我们记 \(a_i\) 表示第 \(i\) 个炉子需顺时针旋转多少次才能到达火力最大的位置,那么对一个区间 \([l,r]\) 进行逆时针旋转 \(c\) 格的操作就等价于令 \([l,r]\) 中的 \(a_i\) 在模 \(7\) 意义下全部加 \(c\),我们要求最少多少次操作才能将其全变为 \(0\)。
这里涉及区间加,因此套路地考虑差分,记差分序列为 \(b\),那么一个区间 \(+c\) 即可转化为两个单点加。乍一看还是不太好做,不过注意如果我们考虑在每次选择的两个点 \(x,y\) 中连一条边,那么最终会得到一张 \(cnt\) 条边的图,其中 \(cnt\) 为操作次数。显然每次单点加操作并不改变 \(b\) 数组的和,而对于图中的每个连通块,该连通块中的点最终的 \(b_i\) 之和为 \(0\),故一开始他们 \(b_i\) 的和也是 \(0\),因此我们可以将题目转化为,将所有 \(b_i\) 划分为尽可能多的组,满足每组的和模 \(7\) 余 \(0\),答案就是 \(n-\)划分次数。
这个划分次数怎么求呢?我们首先求出 \(cnt_v\) 表示有多少个 \(b_i=v\),首先 \(0\) 肯定是单独成一组的,产生 \(cnt_0\) 的贡献,接下来我们肯定希望划分出大小为 \(2\) 的组,而大小为 \(2\) 的组肯定只能由 \((1,6),(2,5),(3,4)\) 配对得到,这样两两配对又能产生一些贡献,配完对后就只剩下三种数 \(x,y,z\) 了,此时可以直接 \(dp_{i,j,k}\) 表示还剩 \(i\) 个 \(x\),\(j\) 个 \(y\),\(k\) 个 \(z\) 最多可以划分为多少组,转移 \(\mathcal O(1)\),总复杂度 \(\dfrac{n^3}{27}\),跑得飞快(
const int MAXN=501;
int n,m,a[MAXN+5],cnt[7],ans=0,dp[MAXN+5][MAXN+5][MAXN+5];
pair<int,int> clr(int x,int y){
return (cnt[x]>cnt[y])?(ans+=cnt[y],mp(x,cnt[x]-cnt[y])):(ans+=cnt[x],mp(y,cnt[y]-cnt[x]));
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
string s;cin>>s;bool flg=0;
for(int j=0;j<7;j++) if(s[j]!=s[0]) flg=1;
if(!flg) continue;
vector<pair<string,int> > vec;
for(int j=0;j<7;j++){
string str;
for(int k=j,stp=0;stp<7;stp++,k=(k+1)%7) str=str+s[k];
vec.pb(mp(str,j));
} sort(vec.begin(),vec.end());
reverse(vec.begin(),vec.end());
a[++m]=vec[0].se;
}
for(int i=m;i;i--) a[i]=(a[i]-a[i-1]+7)%7,cnt[a[i]]++;
ans=cnt[0];
pair<int,int> p1=clr(1,6);
pair<int,int> p2=clr(2,5);
pair<int,int> p3=clr(3,4);//printf("%d\n",ans);
// printf("%d %d %d\n",p1.fi,p2.fi,p3.fi);
// printf("%d %d %d\n",p1.se,p2.se,p3.se);
for(int i=0;i<=p1.se;i++) for(int j=0;j<=p2.se;j++) for(int k=0;k<=p3.se;k++){
chkmax(dp[i+1][j][k],dp[i][j][k]+!(((i+1)*p1.fi+j*p2.fi+k*p3.fi)%7));
chkmax(dp[i][j+1][k],dp[i][j][k]+!((i*p1.fi+(j+1)*p2.fi+k*p3.fi)%7));
chkmax(dp[i][j][k+1],dp[i][j][k]+!((i*p1.fi+j*p2.fi+(k+1)*p3.fi)%7));
} printf("%d\n",m-(ans+dp[p1.se][p2.se][p3.se]));
return 0;
}
洛谷 P4749 - [CERC2017]Kitchen Knobs(差分转换+dp,思维题)的更多相关文章
- 洛谷 P2622 关灯问题II(状压DP入门题)
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 相关变量解释: int n,m; ];//a[i][j] : 第i个开关对第j个 ...
- 洛谷T44252 线索_分治线段树_思维题
分治线段树,其实就是将标记永久化,到最后再统一下传所有标记. 至于先后顺序,可以给每个节点开一个时间戳. 一般地,分治线段树用于离线,只查询一次答案的题目. 本题中,标记要被下传 222 次. Cod ...
- BZOJ5259/洛谷P4747: [Cerc2017]区间
BZOJ5259/洛谷P4747: [Cerc2017]区间 2019.8.5 [HZOI]NOIP模拟测试13 C.优美序列 思维好题,然而当成NOIP模拟题↑真的好吗... 洛谷和BZOJ都有,就 ...
- 洛谷P1067 多项式输出 NOIP 2009 普及组 第一题
洛谷P1067 多项式输出 NOIP 2009 普及组 第一题 题目描述 一元n次多项式可用如下的表达式表示: 输入输出格式 输入格式 输入共有 2 行 第一行 1 个整数,n,表示一元多项式的次数. ...
- [洛谷P3948]数据结构 题解(差分)
[洛谷P3948]数据结构 Description 最开始的数组每个元素都是0 给出n,opt ,min,max,mod 在int范围内 A: L ,R ,X 表示把[l,R] 这个区间加上X(数组的 ...
- 洛谷P3275 [SCOI2011]糖果(差分约束,最长路,Tarjan,拓扑排序)
洛谷题目传送门 差分约束模板题,等于双向连0边,小于等于单向连0边,小于单向连1边,我太蒻了,总喜欢正边权跑最长路...... 看遍了讨论版,我是真的不敢再入复杂度有点超级伪的SPFA的坑了 为了保证 ...
- 洛谷CF809C Find a car(数位DP)
洛谷题目传送门 通过瞪眼法发现,\(a_{i,j}=(i-1)\text{ xor }(j-1)+1\). 二维差分一下,我们只要能求\(\sum\limits_{i=0}^x\sum\limits_ ...
- 洛谷 P6276 - [USACO20OPEN]Exercise P(组合数学+DP)
洛谷题面传送门 废了,又不会做/ll orz czx 写的什么神仙题解,根本看不懂(%%%%%%%%% 首先显然一个排列的贡献为其所有置换环的乘积.考虑如何算之. 碰到很多数的 LCM 之积只有两种可 ...
- 洛谷CF264D Colorful Stones(子序列匹配,思维)
洛谷题目传送门 神仙思维题. 对于两个字符串的匹配问题,似乎之前蒟蒻写的HAOI2010最长公共子序列题解中提到的建网格图模型是一种套路? 给一个稍微强一点的样例(把字母换成了ABC) AABCB B ...
随机推荐
- python3去除行号
问题:在复制一些代码时会同时复制每行的行号,删除比较麻烦,所以利用python3本身的代码进行一键删除. # 导入re 模块来使用正则表达式 import re """去 ...
- Google Object detection配置与使用
Google Object detection 前言: 本文记录了使用Google发布的Object detection(July 1st, 2019)接口,完成了对标注目标的检测.参考了很多博文,在 ...
- 【二食堂】Alpha - Scrum Meeting 9
Scrum Meeting 9 例会时间:4.19 13:00~13:20 进度情况 组员 昨日进度 今日任务 李健 1. "文本区域"栏目完成,可实现实体和关系的添加issue ...
- 2021.8.15考试总结[NOIP模拟40]
T1 送花 线段树.枚举右端点,线段树记录左端点对应的值. 每次对当前颜色上上次出现的位置到上次出现的位置区间减,上次出现的位置到当前位置区间加. $code:$ 1 #include<bits ...
- wifi 热点配置最优信道
wifi热点服务hostapd启动需要配置hostad.conf文件,其中有一个参数channel是用来配置信道的,信道的可选参数如下: # channel 1-14 is 2.4 GHz ; cha ...
- 把二叉树打印成多行 牛客网 剑指Offer
把二叉树打印成多行 牛客网 剑指Offer 题目描述 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行 # class TreeNode: # def __init__(self, x) ...
- 树行DP小结
顾名思义:就是在树上做的DP,依据DFS的性质,在访问过儿子之后返回后将儿子的状态传递给父亲... 先看例题: 此题用贪心也能过,不过正解是DP. 对于树上的DP我们可以直接考虑最优解下各点的状态来方 ...
- Pod 生命周期和重启策略
Pod 在整个生命周期中被系统定义为各种状态,熟悉 Pod 的各种状态对于理解如何设置 Pod 的调度策略.重启策略是很有必要的. Pod 的状态 状态值 描述 Pending API Server ...
- 如何将声学的spectrogram(声谱图)重新反变换成时域语音信号
最近在研究一些信号分析的事情,感兴趣如何将频谱信号反变换成时域信号.fft 与ifft可以顺畅的转变,但是这个是一帧信号,当时间较长的信号再一起是,通过反变换变成一帧一帧的时域信号,如何把他们拼接起来 ...
- 【python+postman接口自动化测试】(1)网络基础知识
一.IP地址 就像每个人都有一个身份证号码 IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址. 查看IP命令: Windows: ipconfig Li ...