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

这道题是分组背包的变形,先用map把每个字符串相应每个数字,然后把同样的字符串归为一类,求出最小的时间,然后累加即可了,这里每一组的最短时间能够用01背包。由于是两人同一时候做,能够知道两人的工作量相差最小时。结束这样的颜色的衣服所用的时间最少。所以能够设背包容量为sum[i]/2,然后求这个容量下的最打容量。然后这组所加的时间就是sum[i]-dp[sum[i]/2].这里还要注意一点,初始化的时候不能初始化为-1,然后将dp[0]=0,由于不一定要恰好,细致理解一下:)

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
int a[15][106],num[106],sum[106],dp[100500];
int main()
{
int n,m,i,j,t,c,ans,liang,k,num1;
char s[20];
map<string,int>hash;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0 && m==0)break;
memset(a,0,sizeof(a));
memset(num,0,sizeof(num));
memset(sum,0,sizeof(sum));
memset(s,0,sizeof(s));
hash.clear();
num1=0;
for(i=1;i<=n;i++){
scanf("%s",s);
if(hash[s]==0){
num1++;hash[s]=num1;
}
}
for(i=1;i<=m;i++){
scanf("%d%s",&c,s);
t=hash[s];
a[t][++num[t]]=c;
sum[t]+=c;
}
ans=0;
for(i=1;i<=num1;i++){
if(num[i]==0)continue;
else{
//memset(dp,-1,sizeof(dp));
memset(dp,0,sizeof(dp));
liang=sum[i]/2;
for(k=1;k<=num[i];k++){
for(j=liang;j>=a[i][k];j--){
//if(dp[j-a[i][k]]!=-1)
dp[j]=max(dp[j],dp[j-a[i][k]]+a[i][k]);
}
}
ans=ans+sum[i]-dp[liang];
}
}
printf("%d\n",ans);
}
return 0;
}

最新文章

  1. mysql系统数据库
  2. C语言 百炼成钢19
  3. Drawable和Bitmap的区别
  4. java适配器模式随笔记
  5. oracle 里面定时执行任务,比如存储过程内容等。
  6. git linux 多工程部署及git默认端口更改
  7. hadoop操作
  8. 导出CSV表格数据
  9. linux系统编程:IO读写过程的原子性操作实验
  10. 求第k小的元素
  11. async 和 await 之异步编程的学习
  12. Android滑动列表(拖拽,左滑删除,右滑完成)功能实现(2)
  13. 简单的if多分支结构练习:用户录入 1-10的数字 , 1-7没奖品 , 8,9,10分别获得 3 2 1 等奖
  14. mysql数据库和JDBC学习
  15. node 链接mysql(自动链接)
  16. 查找-&gt;静态查找表-&gt;顺序查找(顺序表)
  17. 终于明白vim 和 grep 中 的正则表达式的用法, vim 正则表达式 和grep基本正则表达式 几乎一样
  18. HBase的JavaAPI使用
  19. 轻量级桌面 openbox + tint2 + conky + stalonetray + pcmanfm + xcompmgr
  20. Hadoop集群三种作业调度算法介绍

热门文章

  1. 【bzoj2819】Nim DFS序+树状数组+倍增LCA
  2. 【bzoj1941】[Sdoi2010]Hide and Seek KD-tree
  3. HDU——2066一个人的旅行(优先队列SPFA水题)
  4. linux安装websocketd服务
  5. php--转码函数
  6. 在 NetBeans 中开发一般 Java 应用程序时配置 Allatori 进行代码混淆
  7. hdu3947 给一些已知(需费用)路径去覆盖一些边 //预先加灌法费用流
  8. AC日记——教辅的组成 洛谷 P1231
  9. HDU 5733 tetrahedron(计算几何)
  10. C++对象