NOIP模拟测试4「礼物·通讯·奇袭」
礼物、
首先见到期望一定要想dp,看到n的范围无脑想状压,
然后我就只想到这了。
dp方程式还是比较好想的,但是我依然想不出来
略经思考 颓题解
依然不会,随便写了个式子
i状态中不含j
$f[i]=\sum_\limits{j=1}^{j<=n} {f[j]\times p[j] }(买到之前没有的) $$+(1-p[i])\times {f[i]}(由自己转移过来(买到已经买过的)) $
$+1(什么也不买)$
显然不是i吖
然后
$f[i]=\sum_\limits{j=1}^{j<=n} {f[j]\times p[j] }(买到之前没有的) $ $+$ $(1-$$\sum_\limits{j=1}^{j<=n}p[j] )$ $\times f[i]+1(店员什么也没拿)$
观察,等式右面也有fi,如果我们楞做就是高斯消元了
那么移项得
$f[i]=$ $\frac{\sum_\limits{j=1}^{j<=n}f[j]\times p[j]+1} {\sum_\limits{j=1}^{j<=n} p[j]}$
转移就完了
代码
#include<bits/stdc++.h>
#define ll long long
#define A 1<<24
double f[A],p[A];
ll n,m,sum=0,Smily;
void turn(ll x,ll n)
{
ll t=x,num=0,xx[100];
while(x) xx[num++]=x%2,x/=2;
for(ll i=num;i<n;i++)printf("0");
for(ll i=num-1;i>=0;i--)printf("%lld",xx[i]);
puts("");
}
using namespace std;
int main()
{
scanf("%lld",&n);
for(ll i=1;i<=n;i++){
scanf("%lf%lld",&p[i],&Smily);
sum+=Smily;
}
printf("%lld\n",sum);
for(ll i=(1<<n)-2;i>=0;i--){
double now=0;
for(ll j=1;j<=n;j++){
if(!((1<<(j-1))&i))
f[i]+=f[i|(1<<(j-1))]*p[j],now+=p[j];
}
// printf("f=%lf now=%lf\n",f[i],now);
f[i]++;
f[i]/=now;
}
// for(ll i=1;i<=(1<<n)-1;i++)
// {
// printf("%lf\n",f[i]);
// }
printf("%.3lf\n",f[0]);
}
通讯
(有向图)有环不花费,没环有花费,求使所有点连通最小花费。(保证从0节点可以到达任何节点&&图是连通的)
一眼秒错解!!!!!!!
打了个缩点+kuskal,然后自己以为能AC然后完美得到10分
题解
正解,贪心+缩点。
因为保证0可以到任何节点
每次取出当前点入边最小值,得到图依然保持连通,所以贪心正确。
代码懒得放
奇袭
题解
https://blog.csdn.net/sadnohappy/article/details/52199051
https://www.cnblogs.com/12mango/p/7465667.html
耐心看完这两篇博客相信你已经大概理解了。
以下是我自己的一些理解,
首先
$n^3$算法
无脑维护前缀和
MLE+TLE
#include<bits/stdc++.h>
#define ll long long
#define A 10100
using namespace std;
ll a[A][A];
bool b[A][A];
ll n,m,ans=0;
const int L=1<<20|1;
char buffer[L],*S,*T;
#define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
inline int Read(){
register int ret;
register char r;
while(r=getchar(),r<'0'||r>'9');ret=r-48;
while(r=getchar(),r>='0'&&r<='9')ret=ret*10+r-48;
return ret;
}
void dfs(ll k)
{
if(k==n) return ;
for(ll i=1;i<=n-k+1;i++)
for(ll j=1;j<=n-k+1;j++){
if(a[i+k-1][j+k-1]+a[i-1][j-1]-a[i-1][j+k-1]-a[i+k-1][j-1]==k)
ans++/*,printf("k=%lld i=%lld j=%lld a[%lld][%lld]=%lld a[%lld][%lld]=%lld a[%lld][%lld]=%lld a[%lld][%lld]=%lld\n",k,i,j,i+k-1,j+k-1,a[i+k-1][j+k-1],i-1,j-1,a[i-1][j-1],i-1,j+k-1,a[i-1][j+k-1],i+k-1,j-1,a[i+k-1][j-1])*/;
}
dfs(k+1);
}
int main()
{
scanf("%lld",&n);
for(ll i=1;i<=n;i++)
{
ll xx=Read(),yy=Read();
b[xx][yy]++;
}
for(ll i=1;i<=n;i++)
for(ll j=1;j<=n;j++)
{a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+b[i][j];}
// cout<<a[2][4]<<endl;
dfs(2);
cout<<ans+n+1<<endl;
}
$n^2$
略微思考,发现可以把它转换为一维的,行列不重复,所以可以用一个a数组存下来值 a[i]就下标代表第一行,具体存的数就代表第j列
那么我们发现从a[i]-a[j]中a中最大值减a中最小如果为j-i那么就符合题目中所说的子矩阵
维护ST表或单调队列维护,严格$n^2$
约55--64分,看你常数大小
减减枝91
$n\times log n$
一个非常玄学做法,
建议结合代码来看,虽然我知道你不想看代码
玄学二分加桶
这还是我第一次遇到这样的题
事实上该做法是$n^2$的一个优化,思路和它类似a[i]-a[j]中a中最大值减a中最小如果为j-i那么就符合题目中所说的子矩阵。
那么我们二分一个区间时有如下情况
1,当前枚举区间最大值最小值都在mid左面
2,当前枚举区间最大值最小值都在mid右面
3,最小值在左面,最大值在右面
4,最大值在右面,最小值在左面
对于1,我们要做的是扫一遍mid以左就完了,我们max-min+i就是当前区间,要判断j是否>mid 因为即使符合<=mid的情况也会在二分时解决(因为全部在左区间),我们找的最大值最小值都在mid左面,并不一定全在左面,有部分在右面
对于2,做法同1
对于3,我们首先先找到了mid以左最小,以及最大,设mid以左最小minl,最大maxl
我们定义两个指针一个minn指针,一个maxx指针,当前指针都指向mid 因为maxx<=maxl我们要满足3最大值在右面只能往右搜。我们需要找到minn>minl最大位置(因为minn往右搜只会越来越小满足单调性),maxx>ml最小位置(maxx越搜只会越来越大满足单调性)。
找到指针指向位置我们可以断定mid--maxx之间所有方案都不符合3,mid--minn之间可能符合3。
宗上那么maxx--minn之间值可能符合3;
对于”“思路和它类似a[i]-a[j]中a中最大值减a中最小如果为j-i那么就符合题目中所说的子矩阵”“ 这句话 移项
maxx-r==minn-l 我们在桶里存maxx-r 然后找到minn-l对应就完了。
对于4,做法同3
以下是本人丑陋的代码
代码
#include<bits/stdc++.h>
#define ll long long
#define A 1100000
using namespace std;
ll tong[A],lmax[A],lmin[A],rmax[A],rmin[A];
ll a[A];
ll n;
ll work(ll l,ll r,ll mid){
ll w=0;
lmax[mid]=a[mid];lmin[mid]=a[mid];
rmax[mid+1]=a[mid+1];rmin[mid+1]=a[mid+1];
for(ll i=mid-1;i>=l;i--){
lmax[i]=max(lmax[i+1],a[i]);
lmin[i]=min(lmin[i+1],a[i]);
}
for(ll i=mid+2;i<=r;i++){
rmax[i]=max(rmax[i-1],a[i]);
rmin[i]=min(rmin[i-1],a[i]);
}
for(ll i=l;i<=mid;i++){
ll j=i+lmax[i]-lmin[i];
if(j>mid&&rmax[j]<lmax[i]&&rmin[j]>lmin[i]) w++;
}
ll p1=mid+1,p2=mid;
while(p1<=r&&rmax[p1]<lmax[l]) tong[rmax[p1]-p1]--,p1++;
while(p2<r&&rmin[p2+1]>lmin[l]) p2++,tong[rmax[p2]-p2]++;
for(ll i=l;i<=mid;i++){
while(p1>mid+1&&rmax[p1-1]>lmax[i]) p1--,tong[rmax[p1]-p1]++;
while(p2>mid&&rmin[p2]<lmin[i]) tong[rmax[p2]-p2]--,p2--;
w+=max(tong[lmin[i]-i],0ll);
}
for(ll i=mid+1;i<=r;i++){
tong[rmax[i]-i]=0;
}
return w;
}
ll solve(ll l,ll r){
if(l==r) return 1;
ll mid=(l+r)>>1;
ll zz=solve(l,mid)+solve(mid+1,r);
zz+=work(l,r,mid);
reverse(a+l,a+r+1);
if((r-l+1)&1) mid--;
zz+=work(l,r,mid);
reverse(a+l,a+r+1);
return zz;
}
int main(){
scanf("%lld",&n);
for(ll i=1;i<=n;i++){
ll xx,yy;
scanf("%lld%lld",&xx,&yy);
a[xx]=yy;
}
cout<<solve(1,n);
}
NOIP模拟测试4「礼物·通讯·奇袭」的更多相关文章
- NOIP模拟测试19「count·dinner·chess」
反思: 我考得最炸的一次 怎么说呢?简单的两个题0分,稍难(我还不敢说难,肯定又有人喷我)42分 前10分钟看T1,不会,觉得不可做,完全不可做,把它跳了 最后10分钟看T1,发现一个有点用的性质,仍 ...
- NOIP模拟测试30「return·one·magic」
magic 题解 首先原式指数肯定会爆$long$ $long$ 首先根据欧拉定理我们可以将原式换成$N^{\sum\limits_{i=1}^{i<=N} [gcd(i,N)==1] C_{G ...
- NOIP模拟测试38「金·斯诺·赤」
金 辗转相减见祖宗 高精 #include<bits/stdc++.h> using namespace std; #define A 2000 #define P 1 #define N ...
- NOIP模拟测试28「阴阳·虎·山洞」
写这几个题解我觉得我就像在按照官方题解抄一样 阴阳 题解 将题目中给的阴阳看作黑色和白色 首先我们观察到最后生成图中某种颜色必须是竖着单调递增或竖着单调递减 类似这样 否则不满足这个条件 但合法染色方 ...
- NOIP模拟测试20「周·任·飞」
liu_runda出的题再次$\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%$ 任 题解 题目中为什么反复强调简单路径,没有环 没有环的图中点数-边数=联通块数 前缀和维护边 ...
- NOIP模拟测试23「mine·water·gcd」
mine 题解 一道比较水的dp 考试因为初始化挂掉了只有$80$分 代码有注释 #include<bits/stdc++.h> using namespace std; //无脑dp # ...
- NOIP模拟测试16「Drink·blue·weed」
话说这次考试 Drink 非常棒的一道卡常练习题,适合练习卡常 真的很棒 前置卡常知识 1.char要比int快 char是最快的 输出putchar,输入getchar 在这个题快了7000豪 2. ...
- NOIP模拟测试9「随·单·题」
liu_runda出的题,先$\%\%\%\%\%\%\%\%\%\%\%$为敬 随 考试时没有Qj 然后甚至没做,甚至没交 我不知道我怎么想的 这个题挺难改 你需要用到 循环矩阵快速幂,矩阵快速幂优 ...
- NOIP模拟测试21「折纸·不等式」
折纸 题解 考试时无限接近正解,然而最终也只是接近而已了 考虑模拟会爆炸,拿手折纸条试一试,很简单 考你动手能力 代码 #include<bits/stdc++.h> using name ...
随机推荐
- 2-9-9-12分页机制(xp)
10-10-12分页限制 10-10-12分页因为页表PEB只有四个字节所以只能访问2^32 = 4GB物理地址空间,现在的物理内存都大于4GB为了能访问到更多的物理内存2-9-9-12将PEB的大小 ...
- Vue(1):用Vue-cli构建Vue3项目
使用Vue-cli构建Vue3项目 1.检查node版本 node -v 以上node版本位14.15.0满足Vue3项目的创建条件(Vu3需要node 版本8以上) 为什么需要安装node? vue ...
- OO随笔之纠结的第二单元——多线程电梯
综述 主要任务就是写一个电梯模拟器,读入每一个人的请求然后让电梯把他们送到想去的地方. 从第一次到第三次作业,三次的主要任务都是相同的,但是每次都增加了很多的细节,每次的难度都逐步增长,电梯复杂度和瞎 ...
- SQL中那么多函数,Java8为什么还要提供重复的Stream方法,多此一举?
有个同学提出一个这样的疑问; 在业务系统中,数据一般都从sql中查询,类似使用where,order by,limit,聚合函数等,为什么还要用java8的Stream方法? 对这个问题,大家有什么见 ...
- Let's go!
第一次开通博客 心情还是很激动的,而且做出了这么好看的页面虽然都是用的别人的组件,自己不是很知道原理但是也很开心,以后会将自己学习的东西写成笔记发在上面
- 【转载】在python的class中的,self到底是什么?
在python的class中的,self到底是什么? 答案:self可以理解为一个字典变量,内部存的就是对象的数据属性.如:{'name':'zhang','age':'18'}就是这些. 注意只 ...
- python类内部方法__setattr__ __getattr_ __delattr__ hasattr __getattribute__ __getitem__(),__setitem__(), __delitem__()
主要讲类的内部方法 __setattr__ __getattr_ __delattr__ hasattr __getattribute__ __getitem__(),__setitem__ ...
- docker,docker-compose,harbor安装
安装docker-ce 下载docker-ce.repo: wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/li ...
- 第12讲 | TCP协议(下):西行必定多妖孽,恒心智慧消磨难
第12讲 | TCP协议(下):西行必定多妖孽,恒心智慧消磨难 如何做个靠谱的人? 有问有答,任务发送和接收有记录,完成有反馈. 如何实现一个靠谱的协议? TCP 协议使用的也是同样的模式.为了保证顺 ...
- 写Bug时,需要注意的几点3
在对象之间搬移特性 类往往会因为承担过多责任而变得臃肿不堪. (Move Method)搬移函数 含义:在程序中,里面的一个函数与其类外面的一个类或函数有着紧密的调用或者被调用,则需要对其函数内部的表 ...