poj 3211 Washing Clothes 背包
这题做得相当顺利,1A
题意是求夫妇两人洗完衣服用的最小时间。先按衣颜色分类,对于每种颜色的衣服,最优解是都平分即V/2,背包容量为洗衣服的花费,用01背包来标记是否可以通过组合组成某个容量。若不能平均分,就从V/2开始搜索,最接近V/2的较大值就为两人洗完每种颜色衣服的最短时间,把各种颜色衣服的解加起来即为答案
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
const int MAX = 100*1001;
const int N = 101;
bool isvisit[MAX];
int cap[N];
map<string, int> cloth;
vector<int> group[N];
int m, n;
int find(int color)
{
int size = group[color].size();
int sum = 0;
memset(isvisit, false, sizeof(isvisit));
for (int i = 0; i < size; i++)
sum += cap[ group[color][i] ];
isvisit[0] = true;
for (int i = 0; i < size; i++)
for (int v = sum; v >= cap[ group[color][i] ]; v--)
if (!isvisit[v] && isvisit[v - cap[ group[color][i] ] ])
isvisit[v] = true;
int v = sum;
if (sum % 2 == 0)
sum /= 2;
else
sum = sum/2+1;
for (int i = 0; i+sum <= v; i++)
if (isvisit[sum+i])
return sum+i;
}
int main()
{
string s;
while (cin >> m >> n && m||n)
{
cloth.clear();
for (int i = 0; i < m; i++)
{
cin >> s;
cloth[s] = i;
group[i].clear();
}
for (int i = 1; i <= n; i++)
{
cin >> cap[i] >> s;
group[ cloth[s] ].push_back(i);
}
int ans = 0;
for (int i = 0; i < m; i++)
ans += find(i);
cout << ans << endl;
}
return 0;
}
浙公网安备 33010602011771号