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;
}