• 【建兰普及模拟赛第一场】20181023


    T1:真的是简单的模拟,再简单不过了,其实就是求这个里面那个比值最小。
    要注意他当前这个店也是要算在比较的范围内的。

    #include <bits/stdc++.h>
    using namespace std;
    const int Inf=1<<30;
    inline int read() {
    	int w=0,x=0; char ch=0;
    	while (!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    	while (isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	return w?-x:x;
    }
    double Max(double n,double m) {return n>m?n:m;}
    double Min(double n,double m) {return n<m?n:m;}
    int main() {
    	int xncs=read(),ynsc=read(),n=read();
    	double ans=(1.0*xncs)/(1.0*ynsc);
    	for (int i=1;i<=n;i++) ans=Min(1.0*read()/(1.0*read()),ans);
    	printf("%0.2lf
    ",ans*1000);
    	return 0;
    }
    

    T2:真的是简单的模拟,还是非常简单的。我是O(6^3)枚举全部的情况,然后在检查一下是否合法就可以了,要注意字典序要是最小的。

    var
    	st:array[1..6]of string;
    	ans,tmp:string;
    	i,j,k:longint;
    	
    function check(x,y,z:longint):boolean;
    var
    	map:array[1..3,1..3]of char;
    	vis:array[1..6]of boolean;
    	s:string;
    	fg:boolean;
    	i,j,k:longint;
    begin
    	for i:=1 to 6 do vis[i]:=true; vis[x]:=false; vis[y]:=false; vis[z]:=false;
    	for i:=1 to 3 do map[1][i]:=st[x][i];
    	for i:=1 to 3 do map[2][i]:=st[y][i];
    	for i:=1 to 3 do map[3][i]:=st[z][i];
    	for i:=1 to 3 do 
    	begin
    		s:=map[1][i]+map[2][i]+map[3][i];
    		fg:=false;
    		for j:=1 to 6 do 
    			if (j<>x)and(j<>y)and(j<>z) then 
    				if (vis[j])and(s=st[j]) then 
    				begin
    					fg:=true;
    					vis[j]:=false;
    					break;
    				end;
    		if (fg=false) then  exit(false);
    	end;
    	exit(true);
    end;
    
    begin
    	assign(input,'match.in'); reset(input);
    	assign(output,'match.out'); rewrite(output);
    	for i:=1 to 6 do readln(st[i]);
    	ans:='ZZZZZZZZZ';
    	for i:=1 to 6 do 
    		for j:=1 to 6 do 
    		begin
    			if (i=j) then continue;
    			for k:=1 to 6 do 
    			begin
    				if (i=k)or(j=k) then continue;
    				tmp:=st[i]+st[j]+st[k];
    				if (check(i,j,k))and(ans>tmp) then ans:=tmp;
    			end;
    		end;
    	if (ans='ZZZZZZZZZ') then writeln(0)
    	else 
    	begin
    		for i:=1 to 3 do 
    		begin
    			for j:=1 to 3 do write(ans[(i-1)*3+j]);
    			writeln;
    		end;
    	end;
    end.
    

    T3:真的是卡特兰数,我们一般知道的推导公式是

    但是,卡特兰数是非常大的,这里是要%%%的,所以这个公式我们就用不了了。
    所以我们要换一个公式:
    f(n)=f(0)(n-1)+f(1)f(n-1)+...+f(n-1)*f(0)
    这个公式因为是只是涉及到加法的公式,所以我们随便%%%。
    那么就好了。(这道题做不出来,那么就是初赛没有好好复习)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const LL Mod=100000007;
    inline int read() {
    	int w=0,x=0; char ch=0;
    	while (!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    	while (isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	return w?-x:x;
    }
    LL f[3005];
    int main() {
    	freopen("cirs.in","r",stdin);
    	freopen("cirs.out","w",stdout);
    	int n=read();
    	f[1]=f[0]=1; 
    	for (int i=2;i<=n;i++) {
    		for (int j=0;j<i;j++) {
    			f[i]=(f[i]+f[j]*f[i-j-1])%Mod;
    		}
    	}
    	printf("%lld
    ",f[n]);
    	return 0;
    }
    

    T4:真的是动态规划,不知道有没有看出来是背包,算了不管了。
    我们需要知道两大核心,两大思路。
    核心1:状态:F[i][j]表示第i辆车,人数为j的最少钱
    核心2:状态转移方程:
    我们参照一下背包:f[i][j]=max(f[i][j],f[i-1][j-w[i]]+v[i]);
    滚动♂优化:f[j]=max(f[j],f[j-w[i]]+v[i]);
    我们就可以参照一下这个思路,我们就考虑选和不选的情况
    不选就是f[i-1][j],也就是这个车子是空的?Why?因为f[i][j]表示这个车i个人,j个人。但是f[i-1][j]有表示i-1辆车中有j个人,那么就是不是就是这个第i辆车是不是就是没有人了。
    那么选的情况就是f[i-1][j-s]+d+sv
    是不是这个意思,我们枚举一个s就可以了,表示的就是当前这个第i辆车的人数。
    我们要求最小值,那么就去一个min可以了。
    那么我们就滚动优化一下:f[j]=min(f[j],f[j-t]+d+t
    a)
    好像是不是更优了一点QAQ!

    #include <cstdio>
    #include <cstring>
    #include <ctype.h>
    #include <algorithm>
    using namespace std;
    const int Inf=0x3f3f3f3f;
    int n,k,d,s,a,b;
    int f[105][105];
    inline int read() {
    	int w=0,x=0;char ch=0;
    	while (!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    	while (isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 
    	return w?-x:x;
    }
    int main() {
    	n=read(),k=read(),d=read(),s=read(); 
    	memset(f,Inf,sizeof(f));
    	f[0][0]=0;
    	for (int i=1;i<=k;i++) {	
    		a=read(),b=read();
    		for (int j=0;j<=n;j++) {
    			f[i][j]=f[i-1][j];
    			for (int t=0;t<=b;t++) {
    				if (j>=t) f[i][j]=min(f[i][j],f[i-1][j-t]+d+t*a);
    			}
    		}
    	}
    	if (f[k][n]!=Inf) printf("%d
    ",f[k][n]);
    	else printf("impossible
    ");
    	return 0;
    }
    

    (滚动优化,还未测试)

    #include <cstdio>
    #include <cstring>
    #include <ctype.h>
    #include <algorithm>
    using namespace std;
    const int Inf=0x3f3f3f3f;
    int n,k,d,s,a,b;
    int f[105];
    inline int read() {
    	int w=0,x=0;char ch=0;
    	while (!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    	while (isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 
    	return w?-x:x;
    }
    int main() {
    	n=read(),k=read(),d=read(),s=read(); 
    	memset(f,Inf,sizeof(f));
    	f[0]=0;
    	for (int i=1;i<=k;i++) {	
    		a=read(),b=read();
    		for (int j=0;j<=n;j++) {
    			for (int t=b;t>=0;t--) {
    				if (j>=t) f[j]=min(f[j],f[j-t]+d+t*a);
    			}
    		}
    	}
    	if (f[k]!=Inf) printf("%d
    ",f[k]);
    	else printf("impossible
    ");
    	return 0;
    }
    
  • 相关阅读:
    报告论文:数字图像噪音处理研究
    报告论文:汽车GPS调度系统车载终端设计技术方案
    疾病研究:我是一名34岁的进行性肌营养不良症患者
    08年最热门七大技术和最紧缺的IT人才
    C#序列化
    网络游戏的数据管理
    2008年3月Google占美国搜索请求量市场份额达67.3%
    C#反转字符串效率最高的方法
    何时应该使用极限编程
    几种字符串反转方法效率比较
  • 原文地址:https://www.cnblogs.com/Dawn-Star/p/9839351.html
Copyright © 2020-2023  润新知