zoukankan      html  css  js  c++  java
  • 2021.07.01膜你赛

    写在前面:zx gg AK力%%% 以及 youwike gg 太强辣%%%

    lj女士:今天的题就是拼手速,两个小时以内 AK。所以不需要任何交流。然而最后还是交流了

    题面

    A.怪物猎人

    背包+一点贪心思想

    推式子:

    [f(k) = sum_{i=1}^{k} [a_i + (i-1) imes d] imes [b_i + (i-1) imes d] ]

    [f(k) = sum_{i=1}^{k} [a_i imes b_i + (i-1) imes d imes (a_i + b_i) + (i-1)^2 imes d^2] ]

    我们可以看出,第一、三项都是定值,只有第二项 ((i-1) imes d imes (a_i + b_i)) 是不定的

    所以我们按 (a_i+b_i) 降序排序,使得大的数 ( imes d) 的个数尽量小,从而保证答案最小

    (code)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define maxn 3010
    #define maxm 300010
    #define int long long
    using namespace std;
    template<typename T>
    inline void read(T &x){
    	x=0;bool flag=0;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
    	for(;isdigit(c);c=getchar()) x=x*10+(c^48);
    	if(flag) x=-x;
    }
    
    int n,m,d,h[maxm];
    int g[maxn][maxn],f[maxn][maxn];
    struct node{
    	int a;
    	int b;
    }e[maxn];
    
    bool cmp(node x,node y){
    	return x.a+x.b>y.a+y.b;
    }
    
    void dp(){
    	memset(f,0x3f,sizeof(f));
    	for(int i=0;i<=n;i++) f[i][0]=0;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			g[i][j]=(e[j].a+(i-1)*d)*(e[j].b+(i-1)*d);
    		}
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			f[i][j]=min(f[i-1][j],f[i-1][j-1]+g[j][i]);//g[j][i]********
    		}
    	}
    }
    
    signed main(){
    	read(n),read(m),read(d);
    	for(int i=1;i<=n;i++) read(e[i].a);
    	for(int i=1;i<=n;i++) read(e[i].b);
    	for(int i=1;i<=m;i++) read(h[i]);
    	sort(e+1,e+n+1,cmp);
    	dp();
    	for(int i=1;i<=m;i++) printf("%lld ",lower_bound(f[n]+1,f[n]+n+1,h[i])-f[n]-1);
    	printf("
    ");
    	return 0;
    }
    /*
    3 4 5
    50 10 100
    60 200 25
    2000 5400 9350 9400
    //
    0 2 2 3
    */
    

    B.无敌的宠物

    线段树板子,普通线段树 or 树状数组均可

    数据很毒瘤,注意开long long

    C.bamboo

    看懂题就比较好做了

    就是求 (1)(n) 的最小距离

    判一判当前两点是否符合条件(是否能在限制距离内走到),若符合就在这两点之间连条边,跑最短路即可

    D.水杯

    从序列中顺序选数,选的数可加入单调队列的队头或队尾(初始队列为空),求队列最长是多少

    最长上升子序列+最长下降子序列

    附徐神的超短代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define maxn 400010
    #define int long long
    using namespace std;
    template<typename T>
    inline void read(T &x){
    	x=0;bool flag=0;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') flag=1;
    	for(;isdigit(c);c=getchar()) x=x*10+(c^48);
    	if(flag) x=-x;
    }
    
    int n,a[maxn],f[maxn],g[maxn],ans;
    
    signed main(){
    	read(n);
    	for(int i=1;i<=n;i++) read(a[i]);
    	memset(f,0x3f,sizeof(f));
    	memset(g,0x3f,sizeof(g));
    	for(int i=n,res;i>=1;i--){
    		int f1=upper_bound(f,f+n,a[i])-f;
    		int f2=lower_bound(f,f+n,a[i])-f;
    		f[f1]=a[i];
    		a[i]=-a[i];
    		int g1=upper_bound(g,g+n,a[i])-g;
    		int g2=lower_bound(g,g+n,a[i])-g;
    		g[g1]=a[i];
    		int tmp1=0,tmp2=0;
    		if(f[f2]==-a[i]) tmp1=f1-f2;
    		if(g[g2]==a[i]) tmp2=g1-g2;
    		res=min(tmp1,tmp2);
    		ans=max(ans,f1+g1-res+1);
    	} 
    	cout<<ans<<endl;
    }
    /*
    4
    1
    4
    2
    3
    //
    3
    */
    

    E.大白兔的聚会

    ==没有上司的舞会 考过不止一次了

    树形DP 0不选1选

  • 相关阅读:
    20170620_javaweb_小结
    win7电脑关机时间长怎么办
    hadoop环境搭建之关于NAT模式静态IP的设置 ---VMware12+CentOs7
    初识bigdata时的一些技能小贴士
    mysql 免安装版 + sqlyog 安装 步骤 --- 发的有点晚
    Python开发之IDE选择
    Python解释器换源
    Anaconda安装与使用
    安装Python环境
    Python和其他编程语言
  • 原文地址:https://www.cnblogs.com/DReamLion/p/14959611.html
Copyright © 2011-2022 走看看