Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

解题的基本思路

Posted by themo at 2014-04-23 10:25:24 on Problem 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;
} 

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator