• 两船载物问题


    题目

    题目描述:
    给定n个物品的重量和两艘载重量分别为c1和c2的船,问能否用这两艘船装下所有的物品。
    输入:
    输入包含多组测试数据,每组测试数据由若干行数据组成。
    第一行为三个整数,n c1 c2,(1 <= n <= 100),(1<=c1,c2<=5000)。
    接下去n行,每行一个整数,代表每个物品的重量(重量大小不大于100)。
    输出:
    对于每组测试数据,若只使用这两艘船可以装下所有的物品,输出YES。
    否则输出NO。
    样例输入:
    3 5 8
    6
    3
    3
    3 5 8
    5
    3
    4
    样例输出:
    NO
    YES


    思路

    最初思路(错误)

    开始考虑是贪心算法,每次找一个最重的货物,还写了个测试代码:

    #include <stdio.h>
    #include <stdlib.h>
    
    int cmp_data(const void *p, const void *q)
    {
    	const int *a = p;
    	const int *b = q;
    
    	return *b - *a;
    }
    
    int main(void)
    {
    	int i, n, c1, c2, *arr;
    
    	while (scanf("%d", &n) != EOF) {
    		scanf("%d %d", &c1, &c2);
    		arr = (int *)malloc(sizeof(int) * n);
    		for (i = 0; i < n; i ++)
    			scanf("%d", &arr[i]);
    		
    		qsort(arr, n, sizeof(arr[0]), cmp_data);
    
    		// 贪心算法
    		int flag;
    		for (i = 0, flag = 1; i < n; i ++) {
    			if (c1 >= arr[i]) {
    				c1 -= arr[i];
    			} else if (c2 >= arr[i]) {
    				c2 -= arr[i];
    			} else {
    				flag = 0;
    				break;
    			}
    		}
    
    		if (flag) {
    			printf("YES
    ");
    		} else {
    			printf("NO
    ");
    		}
    		
    		free(arr);
    	}
    
    	return 0;
    }


    但是很明显这种做法是错误的,理由就是举出一个反例:3 5 8 5 4 4

    正确的思路

    其实不用考虑两条船的问题,就考虑一条船最多能带多少货物,假设最多带为w,然后看看总共重量sum - w是否小于第二条船的载重量即可,是个0-1背包问题


    AC代码

    #include <stdio.h>
    #include <stdlib.h>
     
    int cmp_data(const void *p, const void *q)
    {
        const int *a = p;
        const int *b = q;
     
        return *a - *b;
    }
     
    int main(void)
    {
        int i, j, n, c1, c2, sum, *arr, **dp;
     
        while (scanf("%d", &n) != EOF) {
            scanf("%d %d", &c1, &c2);
            arr = (int *)malloc(sizeof(int) * (n + 1));
            arr[0] = 0;
            for (i = 1, sum = 0; i <= n; i ++) {
                scanf("%d", &arr[i]);
                sum += arr[i];
            }
             
            qsort(arr, n, sizeof(arr[0]), cmp_data);
     
            // 0-1背包
            dp = (int **)malloc(sizeof(int *) * (n + 1));
            for (i = 0; i <= n; i ++)
                dp[i] = (int *)malloc(sizeof(int) * (c1 + 1));
     
            for (i = 0; i <= c1; i ++)
                dp[0][i] = 0;
            for (i = 0; i <= n; i ++)
                dp[i][0] = 0;
     
            for (i = 1; i <= n; i ++) {
                for (j = 1; j <= c1; j ++) {
                    if (arr[i] > j) {
                        dp[i][j] = dp[i - 1][j];
                    } else {
                        dp[i][j] = (dp[i - 1][j] > arr[i] + dp[i - 1][j - arr[i]]) ? dp[i - 1][j] : arr[i] + dp[i - 1][j - arr[i]];
                    }
                }
            }
     
     
            if (sum - dp[n][c1] <= c2) {
                printf("YES
    ");
            } else {
                printf("NO
    ");
            }
             
            free(arr);
        }
     
        return 0;
    }
    /**************************************************************
        Problem: 1462
        User: wangzhengyi
        Language: C
        Result: Accepted
        Time:20 ms
        Memory:11344 kb
    ****************************************************************/


    有个不认识的同学九度oj和我比赛,昨晚刚进入前10今天就被挤出来了!!!
  • 相关阅读:
    EffectiveC++ 第4章 设计与声明
    EffectiveC++ 第3章 资源管理
    EffectiveC++ 第2章 构造/析构/赋值运算
    EffectiveC++ 第1章 让自己习惯C++
    C++实现离散数学的关系类,支持传递闭包运算
    Vi编辑器入门
    如何查看jdk的版本是32位还是64位
    跨域服务调用基本概念及解决方法
    解决MyEclipse不编译的方法
    网上拒绝复制方法解决
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3181463.html
Copyright © 2020-2023  润新知