2019.9.27 csp-s模拟测试53 反思总结
这个起名方式居然还有后续?!
为什么起名不是连续的?!
T1想了半天,搞出来了,结果数组开小【其实是没注意范围】。T2概率期望直接跳,后来翻回来写发现自己整个理解错了期望的含义【何】。T3错误想到赛道修建结果来了个错误贪心。
关于T2破罐子破摔输出k居然骗了二十分这件事……
T1u:
一开始各种想偏,维护哪种值是奇数或偶数个,考虑每次操作影响哪些值变化…这些全都跑出来了。
大概过了一个世纪那么长,突然想着能不能直接优化操作的过程啊,然后对暴力进行钻研,终于开始想到差分。
然后觉着nq的复杂度过不去,开始对差分进行瞎搞。终于又过了一个世纪那么久,发现差分数组也是可以传递转移的……
两个世纪过去了,没有然后了。
#include<iostream>
#include<cstdio>
using namespace std;
int n,q;
long long ans,f[][],H[][],L[][],sum;
int main()
{
scanf("%d%d",&n,&q);
if(!q){
printf("0\n");
return ;
}
else if(n<=){
for(int i=,r,c,l,s;i<=q;i++){
scanf("%d%d%d%d",&r,&c,&l,&s);
for(int j=r;j<r+l;j++){
for(int k=c;k<=j-r+c;k++){
f[j][k]+=s;
}
}
}
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
ans^=f[i][j];
}
}
printf("%lld\n",ans);
return ;
}
else if(q<=){
for(int i=,r,c,l,s;i<=q;i++){
scanf("%d%d%d%d",&r,&c,&l,&s);
for(int j=r;j<r+l;j++){
H[j][c]+=s;
H[j][j-r+c+]-=s;
}
}
for(int i=;i<=n;i++){
sum=;
for(int j=;j<=n;j++){
sum+=H[i][j];
ans^=sum;
}
}
printf("%lld\n",ans);
return ;
}
else{
for(int i=,r,c,l,s;i<=q;i++){
scanf("%d%d%d%d",&r,&c,&l,&s);
H[r][c]+=s;
L[r][c+]-=s;
H[r+l][c]-=s;
L[r+l][c+l+]+=s;
}
for(int i=;i<=n;i++){
sum=;
for(int j=;j<=n;j++){
H[i][j]+=H[i-][j];
L[i][j]+=L[i-][j-];
sum+=H[i][j]+L[i][j];
ans^=sum;
}
}
printf("%lld\n",ans);
return ;
}
}
T2v:
整个儿弄错了期望这东西,一言难尽。
题目中的最优策略,指的是在以某一概率选到某一个位置的时候,选择拿前面的球或者拿后面的球的其中一种决策产生的贡献,累计上这个球是不是白球的贡献,取最大值。
所以dfs,枚举选到的是哪个位置,累积贡献,除以可选到多少种位置,就是这一状态的期望。
因为搜索到的状态会有很多重复,考虑记忆化搜索。但是表示某一状态的数字可能很大,数组下标无法表述。那么对于数组表示得出来的,就用数组存。其它更大的用map映射解决。
不同长度的状态可能存在数值上相同的情况,例如010和0010。解决方法是在这一长度的再靠前一位打上一个1的标记,例如010->1010,0010->10010,这样表示不同的状态。
#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
int n,k;
char s[];
long long fir;
double ans,num[(<<)];
map<long long,double>m;
double dfs(long long x,int k,int lon){
if(!k)return ;
if(lon<=&&num[x]!=-1.0)return num[x];
else if(m.find(x)!=m.end())return m[x];
double f=,f1=,val1,val2;
long long x1,x2;
for(int i=;i<=lon/;i++){
val1=(x>>(lon-i-))&,val2=(x>>(i-))&;
f1=;
x1=(x>>)&(~((<<(lon-i-))-))|(x&((<<(lon-i-))-));
x2=(x>>)&(~((<<(i-))-))|(x&((<<(i-))-));
f1=dfs(x1,k-,lon-)+val1;
f1=max(f1,dfs(x2,k-,lon-)+val2);
f+=f1*(i==lon-i?1.0:2.0);
}
f/=(double)(lon-);
if(lon<=)num[x]=f;
else m[x]=f;
return f;
}
int main(){
scanf("%d%d",&n,&k);
scanf("%s",s+);
for(int i=;i<=(<<);i++)num[i]=-1.0;
fir=;
for(int i=;i<=n;i++){
fir=(fir<<)+(s[i]=='W');
}
ans=dfs(fir,k,n+);
printf("%.10lf",ans);
return ;
}
T3w:
错误贪心:强行认为每个节点由子节点传上来的路径若有偶数条就自行解决是最优的,奇数条就看当前节点连出去的边目标是不是2,然后无脑传上去。
错误性显而易见……有可能强行传上去的这条会打乱父节点本来可以完整自行配对的组合,给父节点增加一条路径,然后不得不再次穿上去,又增加了长度……还不如在当前节点自行了断。
正解是树形DP。发现最后的总路径数是整棵树路径中的奇度数点数/2。对于每个点,记录它传一条边上去或者不传的时候dp[x][1],dp[x][0],包含子树的最少奇度数点数以及在此基础上的最小总路径长。
一棵一棵子树进行转移。设两个用来统计子树们的最优答案的二元组w1,w2。w1的含义是子树们传了一条边上来,w2是不传让它们两两解决。对于每棵子树y,w1=min(w2+dp[y][1],w1+dp[y][0]),w2=min(w1+dp[y][1],w2+dp[y][0])。比较大小的时候都优先比较奇度数点数c1,再比较路径长度c2。
然后根据当前节点上面这条边的状态和目标状态计算dpx。显然一条边如果已经是目标状态,那么始终不走一定是更优的。如果这条边已经是目标状态,让dp[x][1]=inf。使w1的c1++,w2不变,表示若有边传上来就多一个奇度数点作为收尾,或者没有边传上来就不变,然后dp[x][0]在w1和w2中选择更优的。如果这条边不是目标状态,就让dp[x][0]=inf。w1.c2++。w2.c1++,w2.c2++,表示这个节点作为一个新的开头使奇度数节点增加。依然让dp[x][1]在w1和w2中选择更优的。如果这条边的目标状态是2,就两种情况非inf的部分都做一遍。
#include<iostream>
#include<cstdio>
using namespace std;
const int inf=;
int f[][],opt[],goal[];
struct node{
int c1,c2;
}dp[][],tool;
int n,tot,ver[],head[],edge[],edge1[],Next[];
void add(int x,int y,int z,int w){
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
edge[tot]=z;
edge1[tot]=w;
}
node work(node a,node b,node c,node d){
node e;
if(a.c1+b.c1<c.c1+d.c1){
e.c1=a.c1+b.c1;
e.c2=a.c2+b.c2;
}
else if(a.c1+b.c1==c.c1+d.c1){
if(a.c2+b.c2<c.c2+d.c2){
e.c1=a.c1+b.c1;
e.c2=a.c2+b.c2;
}
else{
e.c1=c.c1+d.c1;
e.c2=c.c2+d.c2;
}
}
else{
e.c1=c.c1+d.c1;
e.c2=c.c2+d.c2;
}
return e;
}
void dfs(int x,int fa){
node w1,w2;
w1.c1=w1.c2=inf;
w2.c1=w2.c2=;
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fa)continue;
opt[y]=edge[i];
goal[y]=edge1[i];
dfs(y,x);
node w11=w1;
w1=work(dp[y][],w1,dp[y][],w2);
w2=work(dp[y][],w11,dp[y][],w2);
}
if(goal[x]==){
w2.c1++;
w1.c2++;
w2.c2++;
dp[x][]=work(w1,tool,w2,tool);
w2.c1--;
w1.c2--;
w2.c2--;
w1.c1++;
dp[x][]=work(w1,tool,w2,tool);
}
else{
if(opt[x]!=goal[x]){
dp[x][].c1=inf,dp[x][].c2=inf;
w2.c1++;
w1.c2++;
w2.c2++;
dp[x][]=work(w1,tool,w2,tool);
}
else{
dp[x][].c1=inf,dp[x][].c2=inf;
w1.c1++;
dp[x][]=work(w1,tool,w2,tool);
}
}
}
int main()
{
scanf("%d",&n);
for(int i=,x,y,z,w;i<n;i++){
scanf("%d%d%d%d",&x,&y,&z,&w);
add(x,y,z,w),add(y,x,z,w);
}
dfs(,);
printf("%d %d\n",dp[][].c1/,dp[][].c2);
return ;
}
结果拖到这会儿才写完。
祝祖国母亲生日快乐。
2019.9.27 csp-s模拟测试53 反思总结的更多相关文章
- 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组
2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色
2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)
2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...
- 2019.8.14 NOIP模拟测试21 反思总结
模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...
- 2019.8.9 NOIP模拟测试15 反思总结
日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...
- 2019.8.1 NOIP模拟测试11 反思总结
延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...
- 9.27 csp-s模拟测试53 u+v+w
T1 u 拿到题感觉他很水,但到死没想到正解,只会骗部分分(我太弱了) 考虑用两个差分数组维护,不同的是最后更新答案是$a[i][j]+=a[i-1][j-1]$,首先考虑在斜着加的起点,就是竖着的直 ...
- 2019.7.27 NOIP模拟测试9 反思总结
先来整理题目 T1题目大意:给出n个数字和一个质数作为模数,一个变量x初始值为1.进行m次操作,每次让x随机乘上n个数中的一个,问m次操作以后x的期望值. 答案一定可以用分数表示,输出分子乘分母逆元的 ...
- [考试反思]0927csp-s模拟测试53:沦陷
很喜欢Yu-shi说过的一句话 在OI里,菜即是原罪 对啊. 都会.谁信呢? 没有分数,你说话算什么呢? 你就是菜,你就是不对,没有别的道理. 最没有用的,莫过于改题大神,这就是菜的借口. 但是其实这 ...
随机推荐
- 「题解」:[BZOJ4558]方
问题: 方 时间限制: 2 Sec 内存限制: 256 MB 题面 题目描述 上帝说,不要圆,要方,于是便有了这道题.由于我们应该方,而且最好能够尽量方,所以上帝派我们来找正方形 上帝把我们派到了一 ...
- 洛谷P3694 邦邦的大合唱
题目背景 BanG Dream!里的所有偶像乐队要一起大合唱,不过在排队上出了一些问题. 题目描述 N个偶像排成一列,他们来自M个不同的乐队.每个团队至少有一个偶像. 现在要求重新安排队列,使来自同一 ...
- 洛谷 P3120 [USACO15FEB]牛跳房子(金)Cow Hopscotch (Gold)
P3120 [USACO15FEB]牛跳房子(金)Cow Hopscotch (Gold) 就像人类喜欢跳格子游戏一样,FJ的奶牛们发明了一种新的跳格子游戏.虽然这种接近一吨的笨拙的动物玩跳格子游戏几 ...
- MUI离线原生打包,利用Android Studio进行原生打包MUI项目
首先从官网http://www.dcloud.io/ 下载HBuilder,用该软件创建一个HTML5的移动APP项目,具体可去官网查看相应的文档. 接下来就是如何将写好的HBuilder引入到我们的 ...
- Spring MVC(十三)--保存并获取属性参数
这里的属性参数主要是指通过request.session.cookie等设置的属性,有时候我们需要将一些请求的参数保存到HTTP的request或者session对象中去,在控制器中也会进行设置和获取 ...
- exiftool(-k)与gui的联合使用
首先下载一个exiftool下载后改名字https://sno.phy.queensu.ca/~phil/exiftool/ 根据自己的操作系统选择,我需要这个 然后下载guihttp://u88.n ...
- An invalid property 'jdbcType ' was found in mapping
大概2种原因: 1 放进去的类型与字段的类型不匹配 2 比较变态,xml中=两边不能有空格! 错误示例如下: #{plat,jdbcType = INTEGER}, 去掉空格后: #{plat,jd ...
- 用this 对方法的扩展
*都是静态方法 this指向的是调用的object*
- 第一周课堂笔记2th
上课笔记2th https://mubu.com/doc/2gxvIvVLG0(老师笔记网址) 1. python python运行过程 把源代码转化成字节码(机器不能识别) 也可能不产生py ...
- mv- Linux必学的60个命令
1.作用 mv命令用来为文件或目录改名,或者将文件由一个目录移入另一个目录中,它的使用权限是所有用户.该命令如同DOS命令中的ren和move的组合. 2.格式 mv[options] 源文件或目录 ...