poj_3211
来源:互联网 发布:空巢青年 知乎 编辑:程序博客网 时间:2024/06/06 21:05
// 01背包,需要计算出每洗的种衣服所需要的最少时间// 从总的时间/2开始枚举01背包#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define MAXV 100001#define MAX_CHAR 20#define MAX_COLOR 11#define MAX_CLOTH 101typedef struct _Node { int pos, arr[MAX_CLOTH];}Node;int dp[MAXV];Node color[MAX_COLOR];char color_type[MAX_COLOR][MAX_CHAR], each_color[MAX_CHAR];int get_color_index(const int &color_cnt, const char *str){ for(int i = 0; i < color_cnt; i ++) { if( !strcmp(str, color_type[i]) ) { return i; } }}int zero_one_knapsack(int tot, int max_v, int color_idx){ memset(dp, 0, sizeof(dp)); for(int i = 0; i < color[ color_idx ].pos; i ++) { for(int v = max_v; v >= color[ color_idx ].arr[i]; v --) { dp[v] = max(dp[v], dp[ v-color[ color_idx ].arr[i] ]+color[ color_idx ].arr[i]); } } if( tot-dp[max_v] <= max_v ) { return dp[max_v]; } return -1;}int main(int argc, char const *argv[]){#ifndef ONLINE_JUDGE freopen("test.in", "r", stdin);#endif int color_cnt, cloth_cnt, need_time, idx, ans, max_v, tot; while( scanf("%d %d", &color_cnt, &cloth_cnt) && color_cnt && cloth_cnt ) { for(int i = 0; i < color_cnt; i ++) { scanf("%s", color_type[i]); } ans = 0; memset(color, 0, sizeof(color)); for(int i = 0; i < cloth_cnt; i ++) { scanf("%d %s", &need_time, each_color); idx = get_color_index(color_cnt, each_color); color[ idx ].arr[ color[ idx ].pos ++ ] = need_time; } for(int i = 0; i < color_cnt; i ++) { max_v = 0; for(int d = 0; d < color[i].pos; d ++) { max_v += color[i].arr[d]; } tot = max_v, max_v >>= 1; for( ; -1 == (idx = zero_one_knapsack(tot, max_v, i)); max_v ++) ; ans += idx; } printf("%d\n", ans); } return 0;}