zoukankan      html  css  js  c++  java
  • nyoj 0325 zb的生日(dp)

    nyoj 0325 zb的生日

    zb的生日

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:2
    描述
    今天是阴历七月初五,acm队员zb的生日。zb正在和C小加、never在武汉集训。他想给这两位兄弟买点什么庆祝生日,经过调查,zb发现C小加和never都很喜欢吃西瓜,而且一吃就是一堆的那种,zb立刻下定决心买了一堆西瓜。当他准备把西瓜送给C小加和never的时候,遇到了一个难题,never和C小加不在一块住,只能把西瓜分成两堆给他们,为了对每个人都公平,他想让两堆的重量之差最小。每个西瓜的重量已知,你能帮帮他么?
    输入
    多组测试数据(<=1500)。数据以EOF结尾
    第一行输入西瓜数量N (1 ≤ N ≤ 20)
    第二行有N个数,W1, …, Wn (1 ≤ Wi ≤ 10000)分别代表每个西瓜的重量
    输出
    输出分成两堆后的质量差
    样例输入
    5
    5 8 13 27 14
    样例输出
    3
    解法1:动态规划
      把所有西瓜重量加起来除以二,用01背包求解最接近一半重量的值,这个值就是其中一堆的重量,因为重量非常大,所以花费时间很多
    代码:
     1 #include <stdio.h>  
     2 #include <string.h> 
     3 #define max(a,b) a>b?a:b 
     4 using namespace std;
     5 const int N = 100010;
     6 int v[21]; 
     7 int dp[N]; 
     8 int main() {
     9     int n;
    10     while(scanf("%d", &n) != EOF) {
    11         memset(dp, 0, sizeof(dp));
    12         int sum = 0;
    13         for(int i = 0; i < n; i++) {
    14             scanf("%d", &v[i]);
    15             sum += v[i];
    16         }    
    17         int W = sum/2; 
    18         for(int i = 0; i < n; i++) {
    19             for(int j = W; j >= v[i]; j--) {
    20                 dp[j] = max(dp[j], dp[j - v[i]] + v[i]);
    21             }
    22         }
    23         printf("%d
    ", sum - 2*dp[W]);
    24     }
    25     return 0;
    26 }
    View Code

    解法2:搜索+剪枝

      本题重量很大,所以花费时间很多,但是西瓜数量非常少,所以可以用搜索+剪枝来做

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n, maxn;
     4 int w[21];
     5 int vs[21];
     6 void dfs(int cur, int sum, int W) {
     7     if(cur == 0) {
     8         maxn = max(maxn, sum);
     9         return;    
    10     }
    11     if(vs[cur] + sum < maxn) return; //剪枝 
    12     if(W >= w[cur]) dfs(cur-1, sum + w[cur], W - w[cur]);
    13     dfs(cur-1, sum, W);
    14 }
    15 int main() {
    16     while(scanf("%d", &n) != EOF) {
    17         maxn = 0;
    18         memset(vs, 0, sizeof(vs));
    19         int sum = 0;
    20         for(int i = 1; i <= n; i++) {
    21             scanf("%d", &w[i]);
    22             sum += w[i];
    23             vs[i] += vs[i-1] + w[i];    
    24         }
    25         dfs(n, 0, sum/2);
    26         printf("%d
    ", sum - 2*maxn);
    27     } 
    28     return 0;
    29 }
    View Code
    作者:kindleheart
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Metasploit自动攻击和选择模块攻击详解
    laravel 通过ftp上传的时候报错 Use of undefined constant FTP_BINARY
    Laravel--文件管理及上传自定义目录及文件名
    在从myql服务器上 取消主从关系和重新构建主从关系
    sql 从服务器取消主从复制
    pecl和pear 的区别和联系
    laravel中打印一个sql语句
    laravel 查询数据库first()返回的数据转数组
    [微信小程序]实现一个自定义遮罩层
    分享CSS3里box-shadow属性的使用方法,包括内阴影box-shadow:inset
  • 原文地址:https://www.cnblogs.com/kindleheart/p/8964000.html
Copyright © 2011-2022 走看看