P1049 [NOIP2001 普及组] 装箱问题

 复制Markdown  展开

题目描述

有一个箱子容量为 VV,同时有 nn 个物品,每个物品有一个体积。

现在从 nn 个物品中,任取若干个装入箱内(也可以不取),使箱子的剩余空间最小。输出这个最小值。

输入格式

第一行共一个整数 VV,表示箱子容量。

第二行共一个整数 nn,表示物品总数。

接下来 nn 行,每行有一个正整数,表示第 ii 个物品的体积。

输出格式

  • 共一行一个整数,表示箱子最小剩余空间。

输入输出样例

输入 #1复制

24
6
8
3
12
7
9
7

输出 #1复制

0

说明/提示

对于 100%100% 数据,满足 0<n≤300<n≤30,1≤V≤200001≤V≤20000。

【题目来源】

NOIP 2001 普及组第四题

代码:

        C++:

#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
vector<int> cost;
int dp[10001][20001];
int main() {
	int v;
	cin >> v;
	int n;
	cin >> n;
	cost.push_back(0);
	for (int i = 0; i < n; i++) {
		int num;
		cin >> num;
		cost.push_back(num);
	}
	for (int i = 1; i <= n; i++) {
		for (int j = v; j >= 0; j--) {
			if (j >= cost[i]) {
				dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - cost[i]] + cost[i]);
			}
			else {
				dp[i][j] = dp[i - 1][j];
			}
		}
	}
	cout << v - dp[n][v] << endl;
	return 0;
}

        Python:

dp = [[0 for i in range(10001)] for j in range(20001)]
cost = []
v = int(input())
n = int(input())
cost.append(0)
for i in range(0, n):
    num = int(input())
    cost.append(num)
for i in range(1, n + 1, 1):
    for j in range(0, v + 1, 1):
        if j >= cost[i]:
            dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - cost[i]] + cost[i])
        else:
            dp[i][j] = dp[i - 1][j]
print(v - dp[n][v])

        JAVA:

package com.my.gududu;

import java.util.*;

public class dadada{
    public static void main(String[] args) {
        int dp[][] = new int[20001][20001];
        int cost[] = new int[10001];
        Scanner input = new Scanner(System.in);
        int v = input.nextInt();
        int n = input.nextInt();
        cost[0] = 0;
        for (int i = 1; i <= n; i++) {
            int num = input.nextInt();
            cost[i] = num;
        }
        for (int i = 1; i <= n; i++) {
            for (int j = v; j >= 0; j--) {
                if (j >= cost[i]) {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - cost[i]] + cost[i]);
                }
            }
        }
        System.out.println(v - dp[n][v]);
    }
}

        C:

#include<stdio.h>
int max(int A, int B) {
    return (A > B) ? A : B;
}
int cost[10001];
int dp[20001];
int main(void) {
    int v;
    scanf("%d", &v);
    int n;
    scanf("%d", &n);
    cost[0] = 0;
    for (int i = 1; i <= n; i++) {
        int num; scanf("%d", &num);
        cost[i] = num;
    }
    for (int i = 1; i <= n; i++) {
        for (int j = v; j >= cost[i]; j--) {
            dp[j] = max(dp[j], dp[j - cost[i]] + cost[i]);
        }
    }
    printf("%d", v - dp[v]);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值