• 友好的生物(状压dp)


    传送门

    还有集训队写的的题解~

    大概思路:

    1.把c[j]乘入属性中。乘完后求的即是:

    2.对于前k-1个属性和第k个属性分别讨论,即

    3.枚举符号序列,最优的情况一定包含在之内 。

    4.把生物按照第k个属性的大小排序,保证了后面的数第k种属性大于前面的,这样减出来第k个属性的差值一定是负值,满足条件。

    #include<bits/stdc++.h>
    #define mod 1000000007
    #define LL long long 
    #define N 100003
    #define INF 2100000000
    using namespace std;
    int read()
    {
        int f=1,x=0;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    int c[10],k;
    struct animal{
        int a[10],ord;
    }p[N];
    bool cmp(const animal &x,const animal &y)
    {
        return x.a[k]<y.a[k];
    }
    int main()
    {
        int n=read();k=read();
        for(int i=1;i<=k;++i)c[i]=read();
        for(int i=1;i<=n;++i)
          for(int j=1;j<=k;++j)
          {
              p[i].a[j]=read();p[i].a[j]*=c[j];p[i].ord=i;//直接将c[j]乘入 
          }
        sort(p+1,p+1+n,cmp);
        int ans=0,t1,t2,minid; 
        for(int i=(1<<(k-1))-1;i>=0;--i)//枚举符号序列,最优的情况一定包含在之内 
        {
            int minn=INF;
            for(int j=1;j<=n;++j)
            {
                int num=0;
                for(int l=k-1;l>=1;--l)num=num+((i&(1<<(l-1)))?p[j].a[l]:(-p[j].a[l]));//前k-1个 
                num-=p[j].a[k];//减一个更大的就满足了负号要求了
                if(num-minn>ans){ans=num-minn;t2=minid,t1=p[j].ord;}//更新ans时是用num-minn判,因为求的是两个生物的属性差 
                if(minn>num){minn=num,minid=p[j].ord;}//minn保存最小的属性和 
            }
        }
        printf("%d",t1,t2,ans);
    } 
    View Code
  • 相关阅读:
    PHP链接xmpp,openfire新增用户,聊天室
    mysql数据库导入导出 授权
    docker容器的跨主机连接
    php编译安装
    WebIM web即时通信 基于openfire+smack的Android、Web、PC开发(一)
    某电商平台开发记要——客服系统
    架构
    kafka-python如何关闭debug日志
    【python编码】 UnicodeDecodeError 分析和解决
    I、Identical Day from 第二届“联想杯”
  • 原文地址:https://www.cnblogs.com/yyys-/p/11402796.html
Copyright © 2020-2023  润新知