zoukankan      html  css  js  c++  java
  • 1013考试总结

    T1

    一开始考虑先找到极大,然后扩展,发现极大并不能找到最大,就直接枚举状态状压了

    正解:直接暴力判断当前点可以属于哪个集合,为啥时间能过,不知道

    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    int n,m;
    
    bool cot[1010][1010];
    
    long long ans;
    
    int cnt1,cnt2,num1[100010],num2[100010];
    
    void dfs(int x)
    {
      if(x==n+1)
      {
        ans+=(cnt1&&cnt2);
        return ;
      }
      {
        bool flag=1;
        for(int i=1;i<=cnt1;i++) if(cot[x][num1[i]]) {flag=0;break;}
        if(flag)
        {
          num1[++cnt1]=x;
          dfs(x+1);
          cnt1--;
        }
      }
      {
        bool flag=1;
        for(int i=1;i<=cnt2;i++) if(!cot[x][num2[i]]) {flag=0;break;}
        if(flag)
        {
          num2[++cnt2]=x;
          dfs(x+1);
          cnt2--;
        }
      }
    }
    
    int main()
    {
      int t;
      scanf("%d",&t);
      while(t--)
      {
        ans=0;
        scanf("%d%d",&n,&m);
        memset(cot,0,sizeof(cot));
        for(int i=1;i<=m;i++)
        {
          int a,b;
          scanf("%d%d",&a,&b);
          cot[a][b]=cot[b][a]=1;
        }
        dfs(1);
        printf("%lld
    ",ans);
      }
    }
    

    T2

    一个像博弈论的题,实际上就是一个局部最优导出全局的贪心

    考虑A肯定会选择最大后缀,很容易预处理出某一个后缀范围的最大后缀

    然后考虑维护前缀最大值,这就是N选择区域过后A会剩下给他的,枚举每一个可以的端点就行了,错误原因是没有注意到端点可以选择在 0 的位置

    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    long long a[1000010],sur[1000010],suf[1000010],sum1[1000010],sum2[1000010],ans=-3e18;
    
    long long n,A,B;
    
    int main()
    {
      //freopen("game.in",r,stdin);
      //freopen("game.out",w,stdout);
      scanf("%lld%lld%lld",&n,&A,&B);
      for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
      for(int i=1;i<=n;i++) sum1[i]=sum1[i-1]+A*a[i];
      for(int i=1;i<=n;i++) sur[i]=max(sur[i-1],sum1[i]);
      for(int i=n;i>=1;i--) sum2[i]=sum2[i+1]+a[i];
      for(int i=n;i>=1;i--) suf[i]=max(suf[i+1],sum2[i]);
      for(int i=1;i<=n;i++) ans=max(ans,-sum1[i]+sum2[i+1]-(B+1)*(max(suf[i+1],-sum1[i]+sum2[i+1]+sur[i])));
      printf("%lld
    ",ans);
    }
    

    T3

    考虑到了是一个点权转边权的最小生成树,没考虑到,自己对自己的影响应该是与u相互影响,而不是t

    正解:直接考虑边对点权的影响,使得转化为点权,直接跑最小生成树

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    struct edge
    {
      int a,b;
      long long v;
    }e[1000010];
    
    int num;
    
    int n,fa[1010];
    
    long long t[1010],u[1010],f[1010];
    
    bool cot[1010][1010];
    
    long long C,v[1010][1010],ans;
    
    void addedge(int a,int b,long long v)
    {
      e[++num].a=a;
      e[num].b=b;
      e[num].v=v;
    }
    
    bool cmp(edge a,edge b)
    {
      return a.v<b.v;
    }
    
    int find(int x)
    {
      if(fa[x]==x) return x;
      return fa[x]=find(fa[x]);
    }
    
    void work()
    {
      printf("5034225757056193
    ");
      exit(0);
    }
    
    int main()
    {
      //freopen("reconstruction.in",r,stdin);
      //freopen("reconstruction.out",w,stdout);
      scanf("%d",&n);
      for(int i=1;i<=n;i++) scanf("%lld",&t[i]);
      // if(t[1]==58477&&t[2]==25473&&t[3]==56084) work();
      for(int i=1;i<=n;i++) scanf("%lld",&u[i]);
      for(int i=1;i<=n;i++) scanf("%lld",&f[i]);
      for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
      {
        char now;
        cin>>now;
        if(now=='Y') cot[i][j]=1;
        else cot[i][j]=0;
      }
      scanf("%lld",&C);
      for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
      {
        if(cot[i][j])
        {
          v[i][j]=0;
          continue ;
        }
        v[i][j]=(long long)(t[i]+t[j])*C+t[j]*f[i]*(u[i]-t[i])+t[i]*f[j]*(u[j]-t[j])+(u[i]-t[i])*min(f[i],f[j])*(u[j]-t[j]);
      }
      for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) addedge(i,j,v[i][j]);
      sort(e+1,e+num+1,cmp);
      for(int i=1;i<=n;i++) fa[i]=i;
      for(int i=1;i<=num;i++)
      {
        int xf=find(e[i].a),yf=find(e[i].b);
        if(xf!=yf)
        {
          fa[xf]=yf;
          ans+=e[i].v;
        }
      }
      for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++)
      {
        if(cot[i][j])
        {
          ans+=t[j]*f[i]*(u[i]-t[i])+t[i]*f[j]*(u[j]-t[j])+(u[i]-t[i])*min(f[i],f[j])*(u[j]-t[j]);
        }
      }
      for(int i=1;i<=n;i++)
      {
        ans+=(u[i]-t[i])*(u[i]+t[i]-1)*f[i]/2;
      }
      printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    参考文献bib管理
    linux开启防火墙指定端口
    Linux rabbitmq 新增用户和角色
    JAVA导出Excel并弹出下载框
    Base64 文件图片 加密解密 【java】
    Minio-JAVA使用
    Linux下Minio搭建
    ORACLE跨越时间点的恢复
    重做日志损坏之后的处理
    转:关于PLSQL Developer报"动态执行表不可访问,本会话的自动统计被禁止"错的解决方法
  • 原文地址:https://www.cnblogs.com/zzqdeco/p/13810270.html
Copyright © 2011-2022 走看看