清橙OJ A1133. 装箱问题 (0-1背包)

题目来源:http://www.tsinsen.com/A1133

最近北京大学因为高考原因OJ登不上了,poj和百练都登不上,改在清华的清橙OJ上做题吧

那么问题来了,清华会不会也要高考阅卷呢?

A1133. 装箱问题

时间限制:1.0s   内存限制:256.0MB  

 

试题来源

NOIP2001 普及组

问题描述
  有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0n<=30),每个物品有一个体积(正整数)。
  要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

输入格式

  第一行为一个整数,表示箱子容量;
  第二行为一个整数,表示有n个物品;
  接下来n行,每行一个整数表示这n个物品的各自体积。

输出格式

  一个整数,表示箱子剩余空间。
  样例输入
24
6
8
3
12
7
9
7

样例输出

0

-----------------------------------------------------

解题思路

0-1背包

dp[v][n] = max( dp[v][n-1], dp[v-a[i]][n-1]+a[i]),          v>=a[i]

           = dp[v][n-1],                                                       v<a[i]

简化为一维数组 dp[v] = max(dp[v], dp[v-a[i]]+a[i])

注意用一维数组时要从va[i]倒着遍历,否则第i次的dp结果会覆盖第i-1次的dp结果

-----------------------------------------------------

代码

 二维dp

#include<iostream>
#include<fstream>
using namespace std;

int dp[20002][35] = {};
int a[35] = {};

int main()
{
#ifndef ONLINE_JUDGE
	ifstream fin("0206_8785.txt");
	int v,n,i,j;
	fin >> v >> n;
	for (i=1; i<=n; i++)
	{
		fin >> a[i];
	}
	fin.close();
	for (i=1; i<=n; i++)
	{
		for (j=v; j>=a[i]; j--)
		{
			dp[j][i] = max(dp[j-a[i]][i-1]+a[i], dp[j][i-1]);
		}
		for (j=a[i]-1; j>=0; j--)
		{
			dp[j][i] = dp[j][i-1];
		}
	}
	cout << v-dp[v][n];
	return 0;
#endif
#ifdef ONLINE_JUDGE
	int v,n,i,j;
	cin >> v >> n;
	for (i=1; i<=n; i++)
	{
		cin >> a[i];
	}
	for (i=1; i<=n; i++)
	{
		for (j=v; j>=a[i]; j--)
		{
			dp[j][i] = max(dp[j-a[i]][i-1]+a[i], dp[j][i-1]);
		}
		for (j=a[i]-1; j>=0; j--)
		{
			dp[j][i] = dp[j][i-1];
		}
	}
	cout << v-dp[v][n];
	return 0;
#endif
}

一维dp

#include<iostream>
#include<fstream>
using namespace std;

int dp[20002] = {};
int a[31] = {};

int main()
{
#ifndef online_judge
	ifstream fin("0206_8785.txt");
	int v,n,i,j;
	fin >> v >> n;
	for (i=0; i<n; i++)
	{
		fin >> a[i];
	}
	fin.close();
	for (i=0; i<n; i++)
	{
		for (j=v; j>=a[i]; j--)						// 倒着遍历,防止第i次循环的结果覆盖第i-1次的结果
		{
			dp[j] = max(dp[j-a[i]]+a[i], dp[j]);
		}
	}
	cout << v-dp[v];
	return 0;
#endif
#ifdef online_judge
	int v,n,i,j;
	cin >> v >> n;
	for (i=0; i<n; i++)
	{
		cin >> a[i];
	}
	for (i=0; i<n; i++)
	{
		for (j=v; j>=a[i]; j--)
		{
			dp[j] = max(dp[j-a[i]]+a[i], dp[j]);
		}
	}
	cout << v-dp[v];
	return 0;
#endif
}

猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/80560844