zoukankan      html  css  js  c++  java
  • poj_3628 动态规划

    题目大意

        有N个数字,大小为a[i], 给定一个数S,用这N个数中的某些数加起来使得结果sum>= S,且sum-S最小,求该最小的sum-S值。

    题目分析

        题意中可知,这N个数字的和肯定大于S。那么可以先判断对于大于S的数s1,能否利用这N个物品的某些组合得到,然后找到最小的s1即可。利用动态规划的思想,设f[i][w] 表示能否利用前i种物品的某个组合加和得到w,有f[i][w] = f[i-1][w] || f[i-1][w-a[i]] + a[i]. 
        那么问题来了,要求的f[i][w]的w的范围是多少呢?设最大的a[i]为A,首先w肯定要大于S,然后w小于S+A。假设w大于等于S+A,那么即使知道了某个 f[i][w]为true(即可以通过N个数的某个组合加和得到w),那么肯定可以通过这N个数字的加和得到 w - a[i] >= S(a[i]为构成w的数字的集合中的任意一个数字)。在选择s1的时候会选择w-a[i]而非w,从而w大于等于S+A没有意义。

    实现(c++)

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #define MAX_HEIGHT 20000005
    int cow_height[25];
    bool f[MAX_HEIGHT];
    int max(int a, int b){
    	return a > b ? a : b;
    }
    int main(){
    	int n, b_height, total_height = 0, max_height = 0;
    	while (scanf("%d %d", &n, &b_height) != EOF){
    		total_height = 0, max_height = 0;
    		for (int i = 0; i < n; i++){
    			scanf("%d", cow_height + i);
    			total_height += cow_height[i];
    			max_height = max(max_height, cow_height[i]);
    		}
    		int m = max_height + b_height;
    		for (int i = 0; i <= m; i++){
    			f[i] = false;
    		}
    		f[0] = true;
    		f[cow_height[0]] = true;
    		for (int i = 1; i < n; i++){
    			for (int w = m; w >= cow_height[i]; w--){
    				f[w] = f[w] || f[w - cow_height[i]];
    			}
    		}
    		for (int i = b_height; i < m; i++){
    			if (f[i]){
    				printf("%d
    ", i - b_height);
    				break;
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    CodeForces 52B Right Triangles 矩阵上的计数
    电影节
    怎样高速生成随机数
    VS2010版快捷键
    两个下拉框选择后取出这两个框的区间值
    vs操作快捷键
    输入框限制,条件是左边输入框输入的数字要小于右边输入框的值,两边输入框要为整型数字。
    DateTime.Parse
    清空文本输入框的值
    sql 随机函数newid()
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4840078.html
Copyright © 2011-2022 走看看