CF 463A && 463B 贪心 && 463C 霍夫曼树 && 463D 树形dp && 463E 线段树
http://codeforces.com/contest/462
要求是否全部的字符都挨着偶数个'o'
#include <cstdio>
using namespace std;
char maz[][];
int n;
int cnt[][];
const int dx[]={,,-,};
const int dy[]={,-,,};
int main(){
scanf("%d",&n);
gets(maz[]);
for(int i=;i<n;i++){
gets(maz[i]);
}
for(int i=;i<n;i++){
for(int j=;j<n;j++){
if(maz[i][j]=='o'){
for(int k=;k<;k++){
int nx=i+dx[k];
int ny=j+dy[k];
if(nx<n&&ny<n&&nx>=&&ny>=){cnt[nx][ny]++;}
}
}
}
}
for(int i=;i<n;i++){
for(int j=;j<n;j++){
if(cnt[i][j]&){puts("NO");return ;}
}
}
puts("YES");
return ;
}
贪心
#include <cstdio>
#include <algorithm>
using namespace std;
long long n,k;
long long cnt[];
char maz[];
int main(){
scanf("%I64d%I64d",&n,&k);
gets(maz);
gets(maz);
for(int i=;i<n;i++)cnt[maz[i]-'A']++;
sort(cnt,cnt+);
long long ans=;
for(int i=;i>=;i--){
if(cnt[i]>=k){
ans+=k*k;
k=;
}
else {
k-=cnt[i];
ans+=cnt[i]*cnt[i];
}
if(k==)break;
}
printf("%I64d\n",ans);
return ;
}
题解意思:
这是一道霍夫曼编码的反问题,把所有边权取反就是霍夫曼树问题,详细证明请看算法导论,大概证明一下:
可以把每次的拿来拆分的每一段的都作为树上的节点,长度为1的值必然是叶节点,会在统计一次后被抛出,这时父节点权值则是子节点权值之和,而且必然是一颗二叉树,这与题目是符合的,也就是说深度越大的叶节点加和的次数越多,那么把最大的那两个节点先放在树里,那么它们的父节点就拥有两个节点之和的性质,那么再添加次大的,如此构建就形成了整棵最优树,(算法导论可以严格证明这是棵最优树,通过反证法),于是除了最大的两个点加了n次,其余的点分别加了n-1,n-2,....2次
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=;
int n;
long long a[maxn];
int main(){
scanf("%d",&n);
long long ans=,sum=;
for(int i=;i<n;i++){scanf("%I64d",a+i);sum+=a[i];}
sort(a,a+n);
ans=sum;
for(int i=;i<n;i++){
ans+=sum;
sum-=a[i-];
}
printf("%I64d\n",ans);
return ;
}
D:Appleman and Tree
树形dp
这是一道树形dp,我一开始想到奇怪的地方去了,什么连通域之类的
对每个点,dp记录使其的所有子树成为单黑或纯白的方式,最后再加上自身的黑/白属性
具体来说
初始化:子树单黑=0,子树纯白=1
单黑=现有单黑*子树纯白+子树单黑*现有纯白
纯白=现有纯白*子树纯白
然后加入自身的属性
如果自身为黑,那么单黑=子树纯白(现有黑:切掉所有子节点成为0)
如果自身为白,那么纯白*=子树纯白(切掉本身使得孤立的方式更多)
#include<cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=;
const long long mod= ;
long long dp[maxn][];
int color[maxn];
vector<int> G[maxn];
bool vis[maxn];
void dfs(int s){
dp[s][]=;
dp[s][]=;
vis[s]=true;
for(int i=;i<G[s].size();i++){
int t=G[s][i];
if(vis[t])continue;
dfs(t);
dp[s][]=(dp[s][]*dp[t][]+dp[s][]*dp[t][])%mod;
dp[s][]=dp[s][]*dp[t][]%mod;
}
if(color[s]==){
dp[s][]=dp[s][];
}
else dp[s][]+=dp[s][];
dp[s][]%=mod;
dp[s][]%=mod;
}
int main(){
int n;
scanf("%d",&n);
for(int i=;i<n;i++){
int temp;
scanf("%d",&temp);
G[temp].push_back(i);
}
for(int i=;i<n;i++)scanf("%d",color+i);
dfs();
printf("%I64d\n",dp[][]);
return ;
}
E:Appleman and a Sheet of Paper
线段树
翻折,当长度>len/2的时候那么就反向翻折,这时候相当于反向了一次,需要反着来统计
看上去思路很清晰但是很麻烦
#include<cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=;
const int maxnode=;
long long w[maxnode];
int cur,s,e,len,n,q;
int num(int i){//返回正确的标号,传入的是从开始的端点所需经过距离
if(cur==){return s+i;}
return e-i;
}
void update(int k,int d){//更新线段树
int tk=k;
k+=n-;
w[k]+=d;
while(k>){
k=(k-)/;
w[k]+=d;
}
}
void inv(int l){//翻转
int tl;
if(l*>len){tl=len-l;cur^=;}//翻转统计的同时就要反向更新了
else tl=l;
for(int i=;i<tl;i++){
int td=num(tl*--i);
int td2=num(i);
update(td,w[td2+n-]);
update(td2,-w[td2+n-]);
}
if(cur)e-=tl;else s+=tl;
len=e-s+;
}
long long query(int a,int b,int k,int l,int r){
if(r<=a||l>=b||l>=r)return ;
if(a<=l&&r<=b){
return w[k];
}
else {
long long v1=query(a,b,k*+,l,(l+r)/);
long long v2=query(a,b,k*+,(l+r)/,r);
return v1+v2;
}
}
int main(){
scanf("%d%d",&n,&q);int tn=n,ttn=n;n=;
while(tn>){n<<=;tn>>=;}
for(int i=;i<ttn;i++)update(i,);
s=;e=ttn-;len=ttn;
while(q--){
int op;
scanf("%d",&op);
if(op==){
int l;
scanf("%d",&l);
inv(l);
}
else{
int l,r;
scanf("%d%d",&l,&r);
if(cur){
l=num(l-);//这里卡我半天因为题目给的是从s开始的序号所以从e开始就要+1,传进的参数要-1
r=num(r-);
}
else {
l=num(l);
r=num(r);
}
if(l>r)swap(l,r);
long long ans=query(l,r,,,n);
printf("%I64d\n",ans);
} }
}
CF 463A && 463B 贪心 && 463C 霍夫曼树 && 463D 树形dp && 463E 线段树的更多相关文章
- Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树
Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树 目录 Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树 0x00 摘要 0x01 背景概念 1.1 词向量基础 ...
- 赫夫曼\哈夫曼\霍夫曼编码 (Huffman Tree)
哈夫曼树 给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的结点离 ...
- C# 霍夫曼二叉树压缩算法实现
知道有的人比较懒,直接贴全部代码. 一开始一次性Code完了压缩部分代码.只调试了2,3次就成功了. 一次性写150行代码,没遇到什么bug的感觉还是蛮爽的. 写解压代码,才发现压缩代码有些细节问题. ...
- 基于python的二元霍夫曼编码译码详细设计
一.设计题目 对一幅BMP格式的灰度图像(个人证件照片)进行二元霍夫曼编码和译码 二.算法设计 (1)二元霍夫曼编码: ①:图像灰度处理: 利用python的PIL自带的灰度图像转换函数,首先将彩色图 ...
- word2vec 中的数学原理二 预备知识 霍夫曼树
主要参考: word2vec 中的数学原理详解 自己动手写 word2vec 编码的话,根是不记录在编码中的 这一篇主要讲的就是霍夫曼树(最优二叉树)和编码. ...
- 霍夫曼编码(Huffman Coding)
霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种. 霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符 ...
- 采用霍夫曼编码(Huffman)画出字符串各字符编码的过程并求出各字符编码 --多媒体技术与应用
题目:有一个字符串:cabcedeacacdeddaaaba,问题: (1)采用霍夫曼编码画出编码的过程,并写出各字符的编码 (2)根据求得的编码,求得各编码需要的总位数 (3)求出整个字符串总编码长 ...
- word2vec中关于霍夫曼树的
再谈word2vec 标签: word2vec自然语言处理NLP深度学习语言模型 2014-05-28 17:17 16937人阅读 评论(7) 收藏 举报 分类: Felven在职场(86) ...
- 霍夫曼编码(Huffman)
题目:有一个字符串:cabcedeacacdeddaaaba,问题: (1)采用霍夫曼编码画出编码的过程,并写出各字符的编码 (2)根据求得的编码,求得各编码需要的总位数 (3)求出整个字符串总编码长 ...
随机推荐
- Python3基础 if嵌套示例
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- spring集成mybatis后,打印SQL语句
网上说mybatis的早前版本配置打印sql还比较简单,在3.0.6之后配置方式修改了. 现在的spring-mybatis.xml配置如下: <bean id="sqlSession ...
- BZOJ3300: [USACO2011 Feb]Best Parenthesis 模拟
Description Recently, the cows have been competing with strings of balanced parentheses and compari ...
- [Err] 1111 - Invalid use of group function
本文为博主原创,未经允许不得转载: 初衷,本想通过group by sql语句查询出不同id下总数在一定范围内的数据,所以产生如下的sql,及错误sql AND STATDATE < ' GRO ...
- stm32 ADC使用方法
void Adc_Init(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AP ...
- LR学习资料
http://ajita.iteye.com/blog/1728243/ 选择哪种方式录制,有以下参考原则: 1 基于浏览器的应用程序推荐使用HTML-based Script 2 不是基于浏览器的应 ...
- python 插值查找
def binary_search(lis, key): low = 0 high = len(lis) - 1 time = 0 while low < high: time += 1 # m ...
- Python day14迭代器,三元表达式,列表解析以及生成器表达式
1.迭代器 str=['sds','ccc','dw'] lit_1=str.__iter__()#获取迭代器 print(lit_1.__next__())#打印下一个值 # 用while做for的 ...
- LIBS+=
ZC: “LIBS+=”是要结合“LIBPATH += ”一起使用的?类似下面的用法: ZC: “LIBS+=”指明lib文件的名称,“LIBPATH += ”指明lib文件的路径.最后还要把DLL文 ...
- Mac安装软件时 提示已损坏的解决方法
进入终端: sudo spctl --master-disable