POJ-3211-Washing Machine 01背包问题求解

1、虽然学习算法真的很难,但是坚持就是自己做到的。困难太多,所以总是要定期的鼓励自己。

2、最近集中在研究背包问题。POJ 的3211题。用背包问题求解。

解体的基本思路

a. 两人完成总时间为sum的问题。问题的解答由背包:W[1-n],V[1-n]完成。要求背包中所有的元素都必须被使用。可以转化为背包问题:Cap = sum, 背包的权重就是它的价值。

b. 3211是多个背包问题的解的求和。每件衣服的颜色都是一个背包问题。要求洗完衣服的最小时间,就是求每种颜色洗完的最短时间。

c. 假设蓝色总的完成时间为X,让两个人洗,且洗完的总时间最短,则两人一起完成的时间,最理想的情况下是X/2。但是由于X/2有时是不能达到的。所以寻找最接近X/2的完成时间就是最优解。

d. dp[i]表示在Cap为i的情况下,由背包物品组成的组合最大值。所以求解dp[X/2]的值,之后该问题的cost = max(dp[X/2], sum - dp[X/2]);

e. 代码如下,写得不好。但是accepted了。逻辑是正确的。

 

// 3211-Washing-Clothes.cpp : Defines the entry point for the console application.
// 转化为0-1背包问题求解
// 思路:背包dp[i],表示时间既是weight,又是value
// sum为总时间,两人用背包中的数据组成的值最接近sum/2,则完成任务sum的时间最短

#include "stdafx.h"
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
int dp[100000];	// dp[i] 表示
typedef struct{
	int type;
	int cost;
}Clothes;
Clothes Cloth[100];
// char Color[10][50];
int Cost(int M, int N);
int max(int a, int b)
{
	return a>b ? a : b;
}
bool comp(Clothes A, Clothes B)
{
	return A.type < B.type;
}

int _tmain(int argc, _TCHAR* argv[]) {
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
	int M, N;
	int i;
	string temp_str;
	map<string, int> color; 
	while(cin>>M>>N) {
		if(M+N == 0)
			break;
		// map清零
		color.clear();
		for(i = 1; i <= M; i++) {
			cin>>temp_str;
			color.insert(make_pair(temp_str, i));
		}
		memset(Cloth, 0, sizeof(Cloth));
		for(i = 0; i < N; i++) {
			cin>>Cloth[i].cost;
			cin>>temp_str;
			Cloth[i].type = color[temp_str];
		}
		// 排序
		sort(Cloth,Cloth+N,comp);
		cout<<Cost(M, N)<<endl;
	}
	return 0;
}

int Cost(int M, int N){
	int i, j, k;
	int time_cost = 0;
	int index = 0, index_e = 0, index_b = 0; // 
	int type = 1;
	int total_sum, half_sum, total_cost = 0;
	for(k = 1; k <= M; k++) {
		memset(dp, 0, sizeof(dp));
		total_sum = 0;
		index_b = index;
		while(Cloth[index].type == type) {
			total_sum += Cloth[index].cost;
			index++;
		}
		index_e = index - 1;
		if(index_e >= index_b) { // index_e < index_b 说明该类型数量为0
			// 0-1 背包问题
			int cap = (total_sum%2) ? (total_sum/2+1) : (total_sum/2);
			for(i = index_b; i <= index_e; i++) {
				for(j = cap; j >= Cloth[i].cost; j--) {
					dp[j] = max(dp[j],dp[j-Cloth[i].cost]+Cloth[i].cost);
				}
			}
			time_cost += max(dp[cap], total_sum-dp[cap]);
		}
		// 下标
		type++;
	}
	return time_cost;
} 

  

posted on 2014-04-23 10:23  themo  阅读(600)  评论(0编辑  收藏  举报

导航