• [四校联考]可爱的小猪???


    猪猪划船

    Description
    6只可爱的猪猪们一起旅游,其中有3只大猪A,B,C,他们的孩子为3只小猪a,b,c。由于猪猪们十分凶残,如果小猪在没有父母监护的情况下,和其他的大猪待在一起,就会被吃掉。
    拦在他们面前的是一条大河,河上有一只只有1个船桨且限载2只猪的小船,只有A,B,C,a会划船。他们独自划船单程需要的时间为tA,tB,tC,ta,如果搭载另一只猪时间翻倍。你需要求出所有小猪过河的最短时间。
    Input
    一行,4个整数,tA,tB,tC,ta。
    Output
    一行,一个整数,表示最短时间。
    Sample Input

    10 10 10 10
    

    Sample Output

    220
    

    HINT
    \(tA,tB,tC,ta\leq100\)
    Solution
    显然是要先将小猪运过去,再把大猪运过去,然后发现此时无合法的方案,再将BbCc大小猪成对运回来,大猪运过去,小猪运过去.
    分类讨论一下即可.

    #define min(a,b) (a<b?a:b)
    int A,B,C,a,ans;
    inline void Aireen(){
    	scanf("%d%d%d%d",&A,&B,&C,&a);
    	//->bc
    	ans+=min(a*6,min((a+C)*3,(a+B)*3));
    	//BC-> Aa-> BbCc<-
    	ans+=min(B,C)*2+min(A,a)*2+(B+C)*2;
    	//BC-> a<-
    	ans+=min(B,C)*2+a;
    	//bc->
    	ans+=min(a*5,min(a*2+C*3,a*2+B*3));
    	printf("%d\n",ans);
    }
    

    小猪星球

    Description
    小猪所在的星系有n个星球,用1~n标号,其中有一些星球之间有单向的隧道相连。由于超时空隧道的存在,通过一个隧道的时间可能为0或负数。现在小猪们决定从1号星球出发,沿着最短路径到达n号星球。
    科学家猪小聪发明了一种神奇的装置,使得飞船在每个隧道中运行的时间都增加一个相同的常数(可以为0或负数),你需要确定这个常数使得旅途的总时间非负且最小。
    Input
    输入文件包含多组数据,第一行为数据组数T。
    对于每一组数据,第一行两个整数V,E,表示星球的个数和隧道的个数。
    接下来E行,每行3个整数i,j,t,表示从i号星球到j号星球有一条耗时为t的单向隧道。
    Output
    共T行,每行一个整数,表示从1号星球到n号星球最短的时间。如果不能从1号星球到达n号星球,输出-1。
    Sample Input

    1
    4 5
    1 2 1
    1 3 1
    2 3 -3
    3 1 1
    3 4 1
    

    Sample Output

    2
    

    HINT
    \(N\leq{100},E\leq\frac{N(N+1)}{2},|t|\leq10^5,i,j\leq{N}\).
    Solution
    floyd判当前点是否有可能存在于到n的最短路中,避免spfa判负环的时候在其他点死循环.
    现在要求使得图中最短路最短且非负的c.二分判负环即可.

    #define N 105
    #define M 5055
    #define INF 100000
    #define inf 505000000
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    int g[N],nxt[M],to[M],w[M],n,m,cnt;
    inline void addedge(int x,int y,int z){
    	nxt[++cnt]=g[x];g[x]=cnt;to[cnt]=y;w[cnt]=z;
    }
    int b[N][N],q[N*M],d[N],dis[N],h,t;bool inq[N];
    inline int chk(int k){
    	for(int i=1;i<=n;++i) d[i]=0,dis[i]=inf,inq[i]=false;
    	int u=1;h=1;t=0;q[++t]=u;++d[u];dis[u]=0;inq[u]=true;
    	while(h<=t){
    		u=q[h++];inq[u]=false;
    		for(int i=g[u];i;i=nxt[i]){
    			if(b[to[i]][n]&&dis[u]+w[i]+k<dis[to[i]]){
    				dis[to[i]]=dis[u]+w[i]+k;
    				if(!inq[to[i]]){
    					if(++d[to[i]]>m) return -1;
    					inq[to[i]]=true;q[++t]=to[i];
    				}
    			}
    		}
    	}
    	return dis[n];
    }
    inline bool chk1(){
    	for(int i=1;i<=n;++i) inq[i]=false;
    	int u=1;h=1;t=0;q[++t]=u;inq[u]=true;
    	while(h<=t){
    		u=q[h++];
    		for(int i=g[u];i;i=nxt[i]){
    			if(!inq[to[i]]){
    				q[++t]=to[i];inq[to[i]]=true;
    			}
    		}
    	}
    	return inq[n];
    }
    int l,r,mid;
    inline void Aireen(){
    	int t=read();
    	while(t--){
    		n=read();m=read();cnt=0;
    		for(int i=1;i<=n;++i) g[i]=0; 
    		for(int i=1,j,k,w;i<=m;++i){
    			j=read();k=read();w=read();addedge(j,k,w);
    		}
    		if(!chk1()){
    			puts("-1");continue; 
    		}
    		for(int i=1;i<=n;++i)
    			for(int j=1;j<=n;++j) b[i][j]=0;
    		for(int i=1;i<=n;++i)
    			for(int j=g[i];j;j=nxt[j]) b[i][to[j]]=1;
    		for(int k=1;k<=n;++k)
    			for(int i=1;i<=n;++i)
    				for(int j=1;j<=n;++j)
    					b[i][j]|=b[i][k]&b[k][j];
    		b[n][n]=true;
    		l=-INF;r=INF;
    		while(l<r){
    			mid=(l+r)>>1;
    			if(chk(mid)>=0) r=mid;
    			else l=mid+1;
    		}
    		printf("%d\n",chk(l));
    	}
    }
    

    小猪送货

    Description
    小猪所在的星系有n个星球从左到右排成一排,用1~n标号。每个星球有建设有一个工厂,住着若干居民。猪粮是猪猪星系的重要的物资,第i个城市的工厂能够生产\(p_i\)个单位的猪粮,第i个城市最多可以卖出\(s_i\)个单位猪粮。对于任意\(1\leq{i<j}\leq{n}\),存在着一条从i到j的单向道路,最多可以通过这条道路运输c个单位的猪粮,你需要计算最多能够卖出多少猪粮。
    Input
    第一行两个整数n,c.
    第二行n个整数,第i个整数表示\(p_i\).
    第三行n个整数,第i个整数表示\(s_i\).
    Output
    一行,一个整数,表示最多可以卖出的猪粮的单位数
    Sample Input

    5 1
    7 4 2 1 0
    1 2 3 4 5
    

    Sample Output

    12
    

    HINT
    \(n\leq{10000},0\leq{c,p_i,s_i}\leq10^9\)
    Solution
    先考虑网络流建图.

    \((s,i)=p_i\;,(i,j)=c(i<j),(i,t)=s_i\).

    求最大流.

    边数太多很尴尬,考虑DP最小割.

    f[i][j]表示前i个点,有j个割与t的连边的最小割.

    \(f[i][j]=min\{f[i-1][j]+j\times{c}+p_i\;,f[i-1][j-1]+s_i\}\).
    即割掉与s的连边时,其还与t相连,此时j条与t相连的点可以流到它,流向t,所以那j条边也得割掉;割掉与t的连边时,不存在从它流向t的边了.

    滚动数组即可.

    #define N 10005
    #define INF 10000000000000ll
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    typedef long long ll;
    ll f[2][N],p[N],s[N],c,ans;
    int n;
    inline void Aireen(){
    	n=read();c=1ll*read();
    	for(int i=1;i<=n;++i) p[i]=1ll*read();
    	for(int i=1;i<=n;++i) s[i]=1ll*read();
    	for(int j=0;j<=n;++j) f[0][j]=f[1][j]=INF;
    	f[1][0]=p[1];f[1][1]=s[1];
    	for(int i=2;i<=n;++i){
    		f[i&1][0]=f[i&1^1][0]+p[i];
    		for(int j=1;j<=n;++j)
    			f[i&1][j]=min(f[i&1^1][j]+1ll*j*c+p[i],f[i&1^1][j-1]+s[i]);
    	}
    	ans=f[n&1][0];
    	for(int j=1;j<=n;++j)
    		ans=min(ans,f[n&1][j]);
    	printf("%lld\n",ans);
    }
    

    小猪数数

    Description
    猪小聪和猪小明在一个小时的时间里,A完了前三题,他们无聊地说:“咱们来玩个游戏消磨时间吧……”
    在这个游戏中,猪小聪和猪小明每个人手上有一台电脑,一开始双方的电脑上的数字都是1。现在猪小聪和猪小明按照任意的顺序执行操作a=a+b(其中a为自己电脑上的数字,b为对方电脑上的数字),例如按照小聪-小明-小明执行后双方的数字为2 5。
    现在在他们玩了若干轮之后,双方电脑上的数字为N,M,可惜的是他们忘记了他们到底玩了多少轮,你需要求出他们至少玩了多少轮。
    Input
    2个整数,表示N,M。
    Output
    1个整数,表示最少玩过的轮数。如果根本不可能出现符合要求的结果,输出-1。
    Sample Input

    2 5
    

    Sample Output

    3
    

    HINT
    N,M和ans均不会爆long long.
    Solution
    类似于更相减损术不除二的步数-1,辗转相除法求一下即可.

    typedef long long ll;
    ll n,m;
    inline ll gcd(ll n,ll m){
    	if(n<=0||m<=0) return -1ll;
    	ll r=n%m,ret=n/m-1ll;
    	while(r){
    		n=m;m=r;r=n%m;ret+=n/m;
    	}
    	if(m>1) return -1ll;
    	return ret;
    }
    inline void Aireen(){
    	scanf("%lld%lld",&n,&m);
    	printf("%lld\n",gcd(n,m));
    }
    

    2017-04-08 17:57:02

  • 相关阅读:
    Socket send函数和recv函数详解
    isdigit()函数用法
    C语言的那些小秘密之字节对齐
    The Five Best Linux BitTorrent Clients
    怎么计算网站高峰期并发量和所需的带宽?
    软件需求包括3个不同的层次 业务需求、用户需求和功能需求
    右键删除选中的行总提示rowIndex
    SQL Server[转]SQL Server中临时表与表变量的区别
    面向对象的软件工程应用浅研
    OO开发思想:面向对象的开发方法(Object oriented,OO)
  • 原文地址:https://www.cnblogs.com/AireenYe/p/15605619.html
Copyright © 2020-2023  润新知