Vijos P1153 猫狗大战

P1153猫狗大战
描述

新一年度的猫狗大战通过SC(星际争霸)这款经典的游戏来较量,野猫和飞狗这对冤家为此已经准备好久了,为了使战争更有难度和戏剧性,双方约定只能选择Terran(人族)并且只能造机枪兵。

比赛开始了,很快,野猫已经攒足几队机枪兵,试探性的发动进攻;然而,飞狗的机枪兵个数也已经不少了。野猫和飞狗的兵在飞狗的家门口相遇了,于是,便有一场腥风血雨和阵阵惨叫声。由于是在飞狗的家门口,飞狗的兵补给会很快,野猫看敌不过,决定撤退。这时飞狗的兵力也不足够多,所以没追出来。

由于不允许造医生,机枪兵没办法补血。受伤的兵只好忍了。555-
现在,野猫又攒足了足够的兵力,决定发起第二次进攻。为了使这次进攻给狗狗造成更大的打击,野猫决定把现有的兵分成两部分,从两路进攻。由于有些兵在第一次战斗中受伤了,为了使两部分的兵实力平均些,分的规则是这样的:1)两部分兵的个数最多只能差一个;2)每部分兵的血值总和必须要尽可能接近。现在请你编写一个程序,给定野猫现在有的兵的个数以及每个兵的血格值,求出野猫按上述规则分成两部分后每部分兵的血值总和。

格式

输入格式

第一行为一个整数n(1<=n<=200),表示野猫现在有的机枪兵的个数。以下的n行每行一个整数,表示每个机枪兵的血格(1<=ai<=40)。

输出格式

只有一行,包含两个数,即野猫的每部分兵的血值总和,较小的一个值放在前面,两个数用空格分隔。

样例1

样例输入1[复制]

3
35
20
32

样例输出1[复制]

35 52

限制

各个测试点1s

提示

TO 狗狗:这道题的数据范围我已经尽量按星际的游戏规则来了,如果你再固执于由于机枪兵的攻击力一定使不能达到某些血格值或者游戏中一定要造农民不能使机枪兵的人数达到200的话,我只能决定将那场猫狗大战的录像公开于世人了!!!



这个是把物品分成相等两部分物品数相差不超过1的背包……

那么设dp[j][k] 为存在不存在 取物品数量为j价值和为k的方案,

存在的话,dp[j][k] = true;

否则	dp[j][k] = false;

那么:if(dp[j][k] == true)	dp[j + 1][k + a[i]] = true;

代码:

/*同时限制取物品数量和容量的背包*/
#include 
       
       
        
        
#include 
        
        
#include 
         
         
          
          
#include 
          
          
           
           
#include 
           
           
             #include 
            
              #include 
             
               #include 
              
                #include 
               
                 #include 
                
                  #include 
                 
                   #include 
                  
                    #include 
                   
                     #include 
                    
                      #include 
                     
                       #include 
                      
                        #include 
                       
                         #include 
                        
                          #define maxn (4000 + 20) #define inf 0x3f3f3f3f #define pi acos(-1.0) using namespace std; typedef long long int LLI; bool dp[110][maxn]; int a[maxn]; int main() { // freopen("in.txt","r",stdin); // freopen("out1.txt","w",stdout); int n,sum = 0; scanf("%d",&n); memset(dp,false,sizeof(dp)); for(int i = 1;i <= n;i ++){ scanf("%d",&a[i]); sum += a[i]; } dp[0][0] = true; for(int i = 1; i <= n;i ++){ for(int j = n / 2;j >= 0;j --){ for(int k = sum / 2;k >= 0;k --){ if(dp[j][k]) dp[j + 1][k + a[i]] = true; } } } int p = sum / 2; while(!dp[n / 2][p]) p --; if(p > sum - p) p = sum - p; printf("%d %d\n",p,sum - p); return 0; } 
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
           
          
          
         
         
       
       

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值