博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2/19 福建四校联考
阅读量:4308 次
发布时间:2019-06-06

本文共 6789 字,大约阅读时间需要 22 分钟。

1.设计图案

给你一个n*m的矩阵,每个格子必须填或者不能填,要用环和1*2的小方块填满它,求方案数。

比如3*2,每个格子都必须填 有6种填法。

n*m<=300  

当时一看就觉得不可做然后就放弃了.....

题解:有个结论:

 

 

状压dp详细就是:

按照从上到下,从左到右dp,用f[i][j][k]表示到第i行j列的格子,轮廓线之上的格子的状态是k的方案数量。

如果这个格子不能填,那么他上面的格子必须被填满,上面格子也被填了的时候f[i][j][k]=f[i][j-1][k](j!=1)或者f[i-1][m][k](j=1)

如果这个格子可以填,那么先看一下它上面那个格子是否填满了,没填满就一定要填,填满了就不能竖着填了。然后看一下能不能横着填就可以了。

设x=2^(j-1)   f[i][j][k^x]+=f[i][j-1][k](j!=1) 或者f[i-1][m][k](j==1)    这句话表示的是填竖着的。

当j!=1时,判断一下是否可以横着填,可以的时候f[i][j][k|(x<<1)]+=f[i][j-1][k]

复杂度 nm * 2^(min(n,m))

实际实现可以滚动数组,这样简单很多。

代码

#include
#include
#define ll long long#include
using namespace std;inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;}int n,m,mod;ll f[2][1<<17];bool b[305][305];bool b2[305][305];int main(){ freopen("design.in","r",stdin); freopen("design.out","w",stdout); n=read();m=read();mod=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) b[i][j]=(bool)read(); if(n
>1))!=k)&&b[i][j-1]) f[nown][k|(x>>1)]=(f[nown][k|(x>>1)]+f[pre][k])%mod; } } pre=1-pre;nown=1-nown;memset(f[nown],0,sizeof(f[nown])); } } ll ans=(f[pre][to]*f[pre][to])%mod; printf("%lld\n",ans); return 0;}

 

 2.最优发射

大意:有一个环,有n个武器,每个武器可以打死一个区间内的人。

多组数据,每次给你很多人,问至少要多少个武器可以全部打死.....

n<=100000  人的总数<=200000

题解做法:

倍增加速贪心。

我的做法:

先删掉没用的边,这样的话就可以保证边的l和r都是递增的。由于数据组数比较多,所以显然不能每次遍历全部边。每个点直接二分一个能盖住它的边中最右能到哪里。

不考虑环,显然是一个dp,可以优化到nlogn  

但是加上环之后就比较麻烦,可以用一个lct维护一下dp路径

从1到m遍历,从每一个点向它能转移的点连边,如果它能越过环,就向m+1连边,这样的话一个点的深度就是它一直到现在的点的dp值。

每个点如果有能跨过环的边,那么就用能跨到的地方右边的第一个点的深度+1更新一下答案。

复杂度nlogn

现场的时候写挂了只有60.

#include
#include
#include
#include
#define INF 2000000000#define ms(x) memset(x,0,sizeof(x))using namespace std;inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;}int n,m,L,qq,ans;int t[400005];int c[200005][2];int fa[200005],size[200005];int rev[200005];int qu[200005],top=0;int tf[200005];bool yes;struct line{ int l,r;}ll[400005];bool cmp(line x,line y){ return (x.l
y.r);}inline bool isroot(int x){
return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}inline void update(int x){size[x]=size[c[x][0]]+size[c[x][1]]+1;}void rotate(int x){ //printf("rotate%d\n",x); int y=fa[x],z=fa[y],l,r; l=(c[y][1]==x),r=l^1; if(!isroot(y)) c[z][c[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[c[x][r]]=y; c[y][l]=c[x][r];c[x][r]=y; update(y);update(x);}void splay(int x){ while(!isroot(x)) { int y=fa[x],z=fa[y]; if(!isroot(y)) { if(c[z][1]==y^c[y][1]==x)rotate(x); else rotate(y); } rotate(x); }}void access(int x){ splay(x); while(fa[x]) { int y=fa[x];splay(y); c[y][1]=x; update(y);splay(x); }}void link(int x,int y){ access(x);splay(x); //rever(c[x][0]); access(y);splay(y); c[y][1]=x;fa[x]=y;}void cut(int x){ access(x);splay(x);fa[c[x][0]]=0;c[x][0]=0;}int get(int x){ int l=1,r=n,mid,ans=-1; while(l<=r) { mid=(l+r)>>1; if(ll[mid].l>x) r=mid-1; else { ans=ll[mid].r; l=mid+1; } } return ans;}int get2(int x){ int l=1,r=m,mid,ans=0; while(l<=r) { mid=(l+r)>>1; if(t[mid]<=x) {ans=mid;l=mid+1;} else {r=mid-1;} } return ans;}int check(int x){ access(x);//splay(x); return size[c[x][0]];}int main(){ freopen("launch.in","r",stdin); freopen("launch.out","w",stdout); n=read();qq=read();L=read(); for(int i=1;i<=n;i++) { ll[i].l=read();ll[i].r=read(); if(ll[i].r
=L) { ll[++n].l=0; ll[n].r=ll[i].r-L; } sort(ll+1,ll+n+1,cmp); int j=1; for(int i=2;i<=n;i++) { if(ll[i].r>ll[j].r) {ll[++j]=ll[i];} } n=j;// for(int i=1;i<=n;i++) printf("%d %d %d\n",i,ll[i].l,ll[i].r); while(qq--) { ms(fa);ms(c);ms(size);ms(rev);t[0]=-1; yes=true;m=read();for(int i=1;i<=m;i++) t[i]=read(); sort(t+1,t+m+1);ans=INF;size[m+1]=1; int j=1; for(int i=2;i<=m;i++) if(t[i]!=t[j]) t[++j]=t[i]; m=j; for(int i=0;i++<=m;i++) size[i]=1; if(yes) for(int i=1;i<=m;i++) { int x=get(t[i]); if(x==-1||x
=t[1]) { ans=min(ans,check(get2(x-L)+1)+1); link(i,m+1); } else link(i,get2(x)+1); } ans=min(ans,check(1)); if(yes) printf("%d\n",ans); } return 0; }

 

 3.传输网络

有m条信息,n个传输装置。

每个装置可以把一个范围a-b内的全部信息转移到c(a<=c<=b),但是需要d点费用

现在要把全部信息都转移到一个点,求最小费用。

m<=10^9 n<=10^5

先离散一下,再用两个线段树维护第一条和最后一条信息到每个点c的距离。

然后按dp做就行了。

现场只写了n^3 dp 只有50分......

#include
#include
#include
#define ll long long#define N 262144#define INF 1000000000000000000LLusing namespace std;inline ll llread(){ ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;}inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;}int n,m,cnt=0;ll ans=INF;int s[300005];struct ma{ int l,r,c; ll d;}a[100005];ll T1[600005],T2[600005];ll query(ll*T,int l,int r){ ll minn=INF; for(l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1) { if(~l&1) minn=min(minn,T[l+1]); if( r&1) minn=min(minn,T[r-1]); } return minn;}void renew(ll*T,int x,ll ad){ T[x+=N]=min(T[x],ad); for(x>>=1;x;x>>=1) T[x]=min(T[x<<1],T[(x<<1)+1]); } void init(){ for(int i=1;i<=N*2;i++) T1[i]=T2[i]=INF;}int main(){ freopen("network.in","r",stdin); freopen("network.out","w",stdout); n=read();m=read(); for(int i=1;i<=n;i++) { a[i].l=read(); a[i].r=read(); a[i].c=s[i]=read(); a[i].d=llread(); } s[n+1]=1; s[n+2]=m; sort(s+1,s+n+3);init(); int j=0; for(int i=1;i<=n+2;i++) { if(s[i]!=s[i-1]) s[++j]=s[i]; }cnt=j; renew(T1,1,0);renew(T2,cnt,0); for(int i=1;i<=n;i++) { a[i].l=lower_bound(s+1,s+cnt+1,a[i].l)-s; a[i].r=upper_bound(s+1,s+cnt+1,a[i].r)-s-1; a[i].c=lower_bound(s+1,s+cnt+1,a[i].c)-s; } for(int i=1;i<=n;i++) { if(a[i].l>a[i].r||a[i].l>cnt||a[i].r>cnt) continue; ll x1=query(T1,a[i].l,a[i].r); ll x2=query(T2,a[i].l,a[i].r); ans=min(ans,x1+x2+a[i].d); renew(T1,a[i].c,x1+a[i].d); renew(T2,a[i].c,x2+a[i].d); } if(ans

 

转载于:https://www.cnblogs.com/FallDream/p/liankao219.html

你可能感兴趣的文章
MapReduce的 Speculative Execution机制
查看>>
大数据学习之路------借助HDP SANDBOX开始学习
查看>>
Hadoop基础学习:基于Hortonworks HDP
查看>>
为什么linux安装程序 都要放到/usr/local目录下
查看>>
Hive安装前扫盲之Derby和Metastore
查看>>
永久修改PATH环境变量的几种办法
查看>>
大数据学习之HDP SANDBOX开始学习
查看>>
Hive Beeline使用
查看>>
Centos6安装图形界面(hdp不需要,hdp直接从github上下载数据即可)
查看>>
CentOS7 中把yum源更换成163源
查看>>
关于yum Error: Cannot retrieve repository metadata (repomd.xml) for repository:xxxxxx.
查看>>
linux下载github中的文件
查看>>
HDP Sandbox里面git clone不了数据(HTTP request failed)【目前还没解决,所以hive的练习先暂时搁置了】
查看>>
动态分区最佳实践(一定要注意实践场景)
查看>>
HIVE—索引、分区和分桶的区别
查看>>
Hive进阶总结(听课总结)
查看>>
大数据领域两大最主流集群管理工具Ambari和Cloudera Manger
查看>>
Sqoop往Hive导入数据实战
查看>>
Mysql到HBase的迁移
查看>>
Sqoop import进阶
查看>>