poj 3211 Washing Clothes 01背包问题

对于 5 6 7 8 9 

先按带价由高到低顺序排序,一人选一个,并不能得到最接近的。

比如 9 8 7 6 5

9 6 5

8 7

所需时间9 + 6+5 = 20

9 8

7 6 5

所需 时间 17少于20


第一版(错误)

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <map>
#include <algorithm>

using namespace std;


#define MAX_C (10+2)
#define MAX_CLOTHER (100+2)

int I[MAX_CLOTHER];
int Clo[MAX_C][MAX_CLOTHER];

int cmp(int a,int b)
{
	return a> b;
}

#define printf //
int m,n;
int main()
{
	while(cin>>m>>n)
	{
		if( m==0 && n==0)
			break;

		printf("m=%d n=%d\n",m,n);
		map<string,int> mapColor;
		memset(I,0,sizeof(I));
		for(int i=1;i<=m;i++)
		{
			string str;
			cin>>str;
			mapColor[str]=i;
			printf("color:%s index:%d\n",str.c_str(),i);
		}
		for(int i=1;i<=n;i++)
		{
			int t,ci;
			string str;

			cin>>t>>str;

			ci = mapColor[str];
			Clo[ci][ I[ci ] ] = t;
			printf("Clo[%d][%d]=%d ci=%d\n",ci,I[ci],t,ci);
			++I[ci] ;



		}
		
		int totaltime = 0;
		for(int i=1;i<=m;i++)
		{
			int time = 0;
			printf("I[%d] = %d\n",i,I[i]);
			if(I[i] == 0)
				continue;

			sort(&Clo[i][0],&Clo[i][ I[i] ],cmp);
			// 9 8 7 6 5
			// 9 6 5  = 20 
			// 8 7

			//但实际上
			//9 8   = 19可以比20少
			//7 6 5
			int ftime=0,stime=0;
			for(int ci = 0; ci <I[i]; ci++)
			{
				printf("Clo[%d][%d] = %d\n",i,ci,Clo[i][ci]);
				int ttime = Clo[i][ci];
				if(ftime <= stime)
				{
					ftime += ttime;
				}
				else
				{
					stime += ttime;
				}

			}


			if(ftime >=stime)
				totaltime += ftime;


		}


		cout<<totaltime<<endl;
	}
}


第二版采用01背包求一堆数最接近一版的那个值

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <map>
#include <algorithm>

using namespace std;


#define MAX_C (10+2)
#define MAX_CLOTHER (100+2)

int I[MAX_CLOTHER];
int Clo[MAX_C][MAX_CLOTHER];

int cmp(int a,int b)
{
	return a> b;
}

#define printf //
#define MAX_V (1000*1000)
bool F[MAX_V+1];
int VMAX;
void ZeroOnePack(int value)
{
	for(int v=VMAX;v>=value;v--)
		F[v] |= F[v - value];
}
int m,n;
int main()
{
	while(cin>>m>>n)
	{
		if( m==0 && n==0)
			break;

		printf("m=%d n=%d\n",m,n);
		map<string,int> mapColor;
		memset(I,0,sizeof(I));
		for(int i=1;i<=m;i++)
		{
			string str;
			cin>>str;
			mapColor[str]=i;
			printf("color:%s index:%d\n",str.c_str(),i);
		}
		for(int i=1;i<=n;i++)
		{
			int t,ci;
			string str;

			cin>>t>>str;

			ci = mapColor[str];
			Clo[ci][ I[ci ] ] = t;
			printf("Clo[%d][%d]=%d ci=%d\n",ci,I[ci],t,ci);
			++I[ci] ;



		}
		
		int totaltime = 0;
		for(int i=1;i<=m;i++)
		{
			int time = 0,sum = 0;
			if(I[i] == 0)
				continue;
		
			memset(F,0,sizeof(F));
			F[0] = true;
			for(int ci=0;ci<I[i];ci++)
				sum += Clo[i][ci];

			VMAX = (sum) /2;

			for(int ci=0;ci<I[i];ci++)
			{
				ZeroOnePack(Clo[i][ci]);
			}

			for(int v= VMAX;v>=0;v--)
				if(F[v])
				{
					time = v;
					break;
				}
			printf("can time:%d\n",time);
			
			if(sum -time > time)
				time = sum -time;
			totaltime += time;
			printf("I[%d] = %d time=%d\n",i,I[i],time);
		}


		cout<<totaltime<<endl;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值