您的位置:首页 > 其它

ACM: 动态规划题 poj 3211 背包变…

2016-05-19 23:25 387 查看
Washing Clothes
Description

Dearboy was so busy recently that now he has piles of clothes to
wash. Luckily, he has a beautiful and hard-working girlfriend to
help him. The clothes are in varieties of colors but each piece of
them can be seen as of only one color. In order to prevent the
clothes from getting dyed in mixed colors, Dearboy and his
girlfriend have to finish washing all clothes of one color before
going on to those of another color.

From experience Dearboy knows how long each piece of clothes
takes one person to wash. Each piece will be washed by either
Dearboy or his girlfriend but not both of them. The couple can wash
two pieces simultaneously. What is the shortest possible time they
need to finish the job?

Input

The input contains several test cases. Each test case begins
with a line of two positive integers M and N
(M < 10, N < 100),
which are the numbers of colors and of clothes. The next line
contains M strings which are not longer than 10 characters
and do not contain spaces, which the names of the colors. Then
follow N lines describing the clothes. Each of these lines
contains the time to wash some piece of the clothes (less than
1,000) and its color. Two zeroes follow the last test case.

Output

For each test case output on a separate line the time the couple
needs for washing.

Sample Input

3 4

red blue yellow

2 red

3 blue

4 blue

6 red

0 0

Sample Output

10

 

题意: 一对情侣洗衣服, 现在有m种颜色的衣服n件, 为了不让混着洗衣服染色了, 所以洗完

     
一种颜色的衣服再洗另外的一种. 现在分配给2个人洗, 求出最小的洗完全部时间.

 

解题思路:

     
1. 每一种衣服都是独立, 因此我们分别求出每一种衣服洗完需要的最小时间, 累加起来即可.

     
2. 每一种衣服时间总和是sum[i], 现在要分配给2个人洗, 怎么样才是最小时间. 即是2个人

        
的洗衣服时间尽可能接近sum[i]/2; 因此, sum[i]/2成为了一个临界值.

         问题分析:

        
(1). 考虑其中一个人, 现在num[i]表示i类衣服的数量, 每件衣服有2中分配结果, 要么

             
分配给这个人洗, 要么不分配给这个人洗. 明显的0-1背包问题.

         (2).
上述的临界值可以看成是背包的容量(时间容量), 每件衣服分配0-1状态. 因此,可

             
以用背包问题求解. 方程: dp[j] = max(dp[j], dp[j-time[i][k]]+time[i][k]);

         (3).
当然这样就是求出其中一个人的需要时间, 但是实际上一类衣服洗完的时间是2个人

             
中时间较大的那一个决定. 因此, 结果: sum[i]-dp[ sum[i]/2 ];

 

代码:

#include
<cstdio>

#include <iostream>

#include <cstring>

using namespace std;

#define MAX 1005

#define MAXSIZE 105

int n, m;

char str[MAXSIZE][12];

int num[MAXSIZE], sum[MAXSIZE], cost[MAX][MAXSIZE];

int dp[MAX*MAXSIZE];

inline int max(int a, int b)

{

 return a > b ? a : b;

}

inline int find(char *ch)

{

 for(int i = 1; i <= m; ++i)

 {

  if( strcmp(str[i], ch) == 0
)

   return
i;

 }

 return -1;

}

int DP(int index, int v)

{

 memset(dp, 0, sizeof(dp));

 for(int i = 1; i <= num[index];
++i)

 {

  for(int j = v; j
>= cost[index][i]; --j)

  {

   dp[j] = max(
dp[j], dp[ j-cost[index][i] ]+cost[index][i] );

  }

 }

 return sum[index]-dp[v];

}

int main()

{

 int i;

// freopen("input.txt", "r", stdin);

 while(scanf("%d %d", &m,
&n) != EOF)

 {

  if(n == 0
&& m == 0) break;

  memset(num, 0,
sizeof(num));

  memset(sum, 0,
sizeof(sum));

  memset(cost, 0,
sizeof(cost));

  for(i = 1; i <=
m; ++i)

   scanf("%s",str[i]);

  char
ch[12];

  int temp;

  for(i = 1; i <=
n; ++i)

  {

   scanf("%d
%s",&temp, ch);

   int index =
find(ch);

   sum[ index ]
+= temp;

   num[ index
]++;

   cost[ index
][ num[index] ] = temp;

  }

  int result =
0;

  for(i = 1; i <=
m; ++i)

   result +=
DP(i, sum[i]/2);

  printf("%d\n",
result);

 }

 return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: