zoukankan      html  css  js  c++  java
  • 洛谷P2340 奶牛会展

    题目背景

    奶牛想证明它们是聪明而风趣的。为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行

    了面试,确定了每头奶牛的智商和情商。

    题目描述

    贝西有权选择让哪些奶牛参加展览。由于负的智商或情商会造成负面效果,所以贝西不希望出展奶牛的智商之和小于零,或情商之和小于零。满足这两个条件下,她希望出展奶牛的智商与情商之和越大越好,请帮助贝西求出这个最大值。

    输入输出格式

    输入格式:
    • 第一行:单个整数N,1 ≤ N ≤ 400

    • 第二行到第N + 1 行:第i + 1 行有两个整数:Si 和Fi,表示第i 头奶牛的智商和情商,−1000 ≤ Si; Fi ≤ 1000

    输出格式:
    输出格式

    • 单个整数:表示情商与智商和的最大值。贝西可以不让任何奶牛参加展览,如果这样做是最好的,输出0

    输入输出样例

    输入样例#1:
    5
    -5 7
    8 -6
    6 -3
    2 1
    -8 -5
    输出样例#1:
    8
    说明

    选择第一头,第三头,第四头奶牛,智商和为−5+6+2 = 3,情商和为7−3+1 = 5。再加

    入第二号奶牛可使总和提升到10,不过由于情商和变成负的了,所以是不允许的

    【题解】

    此题为特殊的0-1背包问题。我们可以以情商为物品容量,智商为价值,将其转为正规的01背包问题。(楼下题解认为此方法未看到本质,但这种方法也能AC,但也可能是我造化太浅)

    一点小优化(状压 DP):数组的下标和值都可以存储信息,所以我们可以把智商存在下标上,情商存在值上。

    最后要注意:C++ 中没有负数下标,所以我们需要把 dp 数组平移 m(背包容量、为正数情商之和) 位。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int w[105]={},f[105]={},ff[200010]={};
    int main()
    {
        int n,m=0;
        //freopen("smrtfun.in","r",stdin);
        //freopen("smrtfun.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
          scanf("%d%d",&w[i],&f[i]);//w数组存智商,f数组存情商(w变下标,f变值) 
          if(w[i]>0) m+=w[i];//计算背包容量(情商) 
        }
        m*=2;//m是平移的位数 
        memset(ff,-127/3,sizeof(ff)); 
        ff[m/2]=0;
        for(int i=1;i<=n;i++)
        {
            if(w[i]>0)//根据w[i]的符号确定循环方向,消除后效性,并从这里开始数组平移,防止出现负下标 
            for(int j=m;j>=w[i];j--)//接下来是01背包问题模板,保证每件物品只选一次 
              ff[j]=max(ff[j],ff[j-w[i]]+f[i]);
            else
            for(int j=0;j<=m-w[i];j++)//这个循环是数组平移弄出来的,由上个循环经数学运算得来。上个循环是m->w[i],两边乘-1,变成-w[i]**<-**-m,再加m,即得到m-w[i]**<-**0 
              ff[j]=max(ff[j],ff[j-w[i]]+f[i]);
        }
        int ans=0,k=m/2;//k是平移的位数
        for(int i=0;i<=k;i++)
          if(ff[i+k]>=0 && i+ff[i+k]>ans)//ff[i+k]存的是情商,必须判断非负数,而从0开始的下标保证智商没负数 
            ans=i+ff[i+k];////i是智商,ff[i+k]是情商 
        printf("%d",ans);
        //fclose(stdin);
       // fclose(stdout);
        return 0;
    }
  • 相关阅读:
    编写 grunt 插件经验
    Sencha Touch 手机移动开发框架 HTML5 项目压缩方案;
    随笔 编辑推荐 上头条了, 贴出来做个记念!
    Javascript 俄罗斯方块 游戏代码解释!
    30天自制操作系统(NASM+GCC版)
    Logisim 打不开的解决方案(Windows10)
    Kali Linux 2020通过UEFI硬盘安装(免u盘)
    开源一个自制的ORM框架,基于Java原生JDBC(应该是全网首个吧)
    书单
    前端技术文章收集
  • 原文地址:https://www.cnblogs.com/yanshannan/p/7375739.html
Copyright © 2011-2022 走看看