20190824
Posted lsyyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20190824相关的知识,希望对你有一定的参考价值。
一.友好的生物
我去看了神仙陈启峰2016的论文
1.首先我们假设K=3,并且忽略
"但是属性K与众不同,这种属性差别越小的两种生物越友好"这一条件
那么对于任意a,b
那么 (±a.k[1]±a.k[2]±a.k[3])-(±b.k[1]±b.k[2]±b.k[3])
因为根据常理 c-d<=|c-d|
也就是说只有在符号正确的情况下,我们才能得到最大差值
在2^k的枚举下前后同号
如何优化?
假设我们从左向右依次枚举,得到当前最小值Min,那么后面减Min一定更优
2.因为属性K与众不同,这种属性差别越小的两种生物越友好
那么我们按K从小到大排序,以来保证K的属性差别越小
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) char c;bool f=0; while((c=getchar())<‘0‘||c>‘9‘)if(c==‘-‘)f=1; x=c^48; while((c=getchar())>=‘0‘&&c<=‘9‘)x=x*10+(c^48); if(f)x=-x; const int maxn=100005; int n,m,C[6]; struct node int k[6]; bool operator<(node b)const re k[m]<b.k[m]; a[maxn]; int main() rd(n),rd(m); inc(i,1,m)rd(C[i]); inc(i,1,n) inc(j,1,m) rd(a[i].k[j]); a[i].k[j]*=C[j]; sort(a+1,a+n+1); int S=1<<(m-1),ans=0,Min; inc(s,0,S) Min=10000000; inc(i,1,n) int now=0; inc(j,1,m-1) if(s&(1<<(j-1))) now+=a[i].k[j]; else now-=a[i].k[j]; now-=a[i].k[m]; ans=max(ans,now-Min); Min=min(Min,now); printf("%d",ans); re 0;
二.基因重组
Juicepry®是一个世界著名的实验室。目前,实验室的科学家们正致力于对生物基因的重组进行深入研究。基因的物质载体是脱氧核糖核酸(DNA)。DNA是一种仅由A、T、G、C四种基元构成的双螺旋结构的有机分子。
DNA的两条单链上,同一位置的两个基元是互相对应的。A对T,G对C,因此,我们只需用任意一条链上的基元排列,就可以表示DNA的分子结构。例如:ATTGAGCCGTAT。
由于DNA微小而复杂,重组DNA极其困难,科学家们打算利用一条现成的DNA链作原材料拼接成另外一条新的DNA链。即使这样,拼接DNA仍然是一件繁重的工作,非人力所能胜任。所以科学家们制造了一种手术机器人TuringM来完成这项任务。TuringM每次只能在目标链(T)的右端与原材料 (S) 的左端进行操作。它有下列几种基本拼接操作:
对于每种操作,机器人的单位时间耗费如上表所示(单位:分钟)。最后剩余的原材料自动丢弃。
现在的任务是请你编一个程序,帮助科学家们找出完成DNA链拼接的最少时间。
可怜八月二十四,LL不会做dp
二.危险的迷宫
近来发现了一个古老的地下迷宫,已探明该迷宫是一个A行B列的矩阵,该迷宫有N个不同的出口与N个不同的入口,任一单元格不会既为入口又为出口。为了进一步探明与发掘该迷宫,N个考古队员分别从地上的N个不同的入口进入迷宫,并且计划从N个不同的出口出来。每个队员任意选择一个出口出来,但任意两名队员不会选择同一个出口。
迷宫中的每一格与其相邻的某些格相通。该迷宫设计非常精妙,在不知道具体机关的情况下,人一旦离开其所在格后,该格将迅速关闭,且再也不能开启,也就是说每一格仅能进入一次。更糟的是,迷宫中的每一格都有一定的危险性,专家们用1至100的整数表示,数值越大表示越危险。正因为如此,再加之每一格都不很宽敞,两人一起进入比较危险,所以规定不能两个人同时进入同一格。
为了队员们的安全着想,希望你能够编程求出如何使队员们所经过单元格的危险性总和最小。
【样例解释】
有如下迷宫:
每一格中的数字表示该格的危险程度。两格间若有空缺,表示这两格相通。
入口有两个:(1,1)即第一行第一列,(1,2)即第一行第二列
出口也有两个:(2,3)即第二行第三列,(3,4)即第三行第四列
两名队员的最好的行动方案之一,如上图红蓝箭头所示。危险程度之和最小为235。
莫说了,最小费用最大流模板
#include<bits/stdc++.h> #define re return #define ll long long #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) char c;bool f=0; while((c=getchar())<‘0‘||c>‘9‘)if(c==‘-‘)f=1; x=c^48; while((c=getchar())>=‘0‘&&c<=‘9‘)x=x*10+(c^48); if(f)x=-x; const int maxn=305; int n,m,K,V,s,k=1,t,C,hd[maxn]; int cur[maxn],dis[maxn],vis[maxn]; struct node int to,nt,flow,cost; e[100000]; inline void add(int x,int y,int flow,int w) e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].flow=flow;e[k].cost=w; e[++k].to=x;e[k].nt=hd[y];hd[y]=k;e[k].flow=0; e[k].cost=-w; inline bool bfs() inc(i,1,t) dis[i]=214545444; dis[s]=0; queue<int>q; q.push(s); while(!q.empty()) int u=q.front(); vis[u]=0; q.pop(); for(int i=hd[u];i;i=e[i].nt) int v=e[i].to; if(dis[v]>dis[u]+e[i].cost&&e[i].flow) dis[v]=dis[u]+e[i].cost; if(!vis[v])q.push(v); vis[v]=1; re dis[t]!=214545444; inline int dfs(int u,int flow) if(u==t) C+=flow*dis[t]; re flow; int delta=flow; for(int &i=cur[u];i;i=e[i].nt) int v=e[i].to; if(dis[v]==dis[u]+e[i].cost&&e[i].flow) int d=dfs(v,min(delta,e[i].flow)); e[i].flow-=d;e[i^1].flow+=d; delta-=d; if(!delta)re flow; re flow-delta; int main() freopen("maze.in","r",stdin); freopen("maze.out","w",stdout); int x1,x2,y1,y2,x,y; rd(n),rd(m); int tot=n*m; s=tot+tot+1; t=s+1; inc(i,1,n) int v=(i-1)*m; inc(j,1,m) rd(x); add(v+j,v+j+tot,1,x); rd(K); inc(i,1,K) rd(x1),rd(y1),rd(x2),rd(y2); add((x1-1)*m+y1+tot,(x2-1)*m+y2,1,0); add((x2-1)*m+y2+tot,(x1-1)*m+y1,1,0); rd(V); inc(i,1,V) rd(x),rd(y); add(s,(x-1)*m+y,1,0); inc(i,1,V) rd(x),rd(y); add((x-1)*m+y+tot,t,1,0); int ans=0; while(bfs()) inc(i,1,t)cur[i]=hd[i]; ans+=dfs(s,V); if(ans==V) printf("%d",C); else printf("-1"); re 0;
以上是关于20190824的主要内容,如果未能解决你的问题,请参考以下文章