修理桌子 算法求解。

lppl010_ 2016-04-01 12:02:39
//修理桌子
//Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
//Problem Description:
//Arthur最近搬到了新的别墅,别墅特别大,原先的桌子显得比较小,所以他决定换一张新的桌子。
//他买了一张特别大的桌子,桌子是由很多条桌腿进行支撑的,
//可是回到家之后他发现桌子不稳,原来是桌子腿长度不太相同。
//他想要自己把桌子修理好,所以他决定移除掉一些桌腿来让桌子变得平稳。
//桌子腿总共有n条腿,第i条腿长度为li,Arthur移除第i桌腿要花费代价为di。
//假设k条腿桌子平稳的条件:超过一半桌腿能够达到桌腿长度的最大值。
//例如:一条腿的桌子是平稳的,两条腿的桌子腿一样长时是平稳的。
//请你帮Arthur计算一下是桌子变平稳的最小总代价。
//输入
//第一行数据是一个整数:n (1≤n≤105),n表示桌腿总数。
//第二行数据是n个整数:l1, l2, ..., ln (1≤li≤105),表示每条桌腿的长度。
//第三行数据是n个整数:d1, d2, ..., dn (1≤di≤200),表示移除每条桌腿的代价。
//输出
//输出让桌子变平稳的最小总代价
//样例输入
//6
//2 2 1 1 3 3
//4 3 5 5 2 1
//样例输出
//8
...全文
571 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
haifeng_xd 2016-04-06
  • 打赏
  • 举报
回复
能不能大概说一下算法过程
棒子先生 2016-04-03
  • 打赏
  • 举报
回复
给出基本代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

#define LEG_NUM_MAX		105

struct desk_leg {
	int cost;
	int len;
	int num;
};

struct desk {
	struct desk_leg **leg;
	int leg_num;

	struct desk_leg **sleg;
	int type_num;
};

struct desk* create_desk(int leg_num)
{
	int j;

	struct desk *pdesk;

	if (!(pdesk = malloc(sizeof(struct desk))))
		goto failed1;

	if (!(pdesk->leg = calloc(leg_num, sizeof(void *))))
		goto failed2;
	if (!(pdesk->sleg = calloc(leg_num, sizeof(void *))))
		goto failed22;
	
	for (j = 0; j < leg_num; j++) {
		if (!(pdesk->leg[j] = malloc(sizeof(struct desk_leg))))
			goto failed3;
	}

	for (j = 0; j < leg_num; j++) {
		if (!(pdesk->sleg[j] = malloc(sizeof(struct desk_leg))))
			goto failed4;
		else {
			pdesk->sleg[j]->num = 1;
		}
	}

	pdesk->leg_num = leg_num;
	pdesk->type_num = leg_num;

	return pdesk;
	
failed4:
	for (j = j - 1; j >= 0; j--)
		free(pdesk->sleg[j]);

failed3:
	for (j = j - 1; j >= 0; j--)
		free(pdesk->leg[j]);
	free(pdesk->sleg);

failed22:
	free(pdesk->leg);

failed2:
	free(pdesk);

failed1:
	return NULL;
}

void init_desk_for_test(struct desk *pdesk) 
{
#if LEG_NUM_MAX == 6
	int cost[LEG_NUM_MAX] = { 4, 3 ,5, 5, 2, 1 };
	int len[LEG_NUM_MAX] = { 2, 2 ,1, 1, 3, 3 };

	for (int i = 0; i < pdesk->leg_num; i++) {
		pdesk->leg[i]->cost = cost[i];
		pdesk->leg[i]->len = len[i];
	}

#else
	for (int i = 0; i < pdesk->leg_num; i++) {
		pdesk->leg[i]->cost = rand() % 10 + 1;
		pdesk->leg[i]->len = rand() % 10 + 1;
	}
#endif
}

void delete_desk(struct desk *pdesk)
{
	for (int i = 0; i < pdesk->leg_num; i++)
		free(pdesk->leg[i]);
	for (int i = 0; i < pdesk->leg_num; i++)
		free(pdesk->sleg[i]);
	free(pdesk->leg);
	free(pdesk->sleg);
	free(pdesk);
}

void show_desk_info(struct desk *pdesk)
{
#if 1
	printf("desk has [%d] legs:\r\n", pdesk->leg_num);

	for (int i = 0; i < pdesk->leg_num; i++)
		printf("\tleg length %d, cost %d, num is %d\n", 
			pdesk->leg[i]->len, 
			pdesk->leg[i]->cost,
			pdesk->leg[i]->num);
#endif
	printf("\r\ndesk has [%d] slegs:\r\n", pdesk->type_num);
	for (int i = 0; i < pdesk->type_num; i++)
		printf("\tsleg length %d, cost %d, num is %d\r\n", pdesk->sleg[i]->len, pdesk->sleg[i]->cost, pdesk->sleg[i]->num);
}

void sort_leg_by_cost(struct desk_leg **pleg, int leg_num)
{
	for (int i = 1; i < leg_num; i++) {
		for (int j = i - 1; j >= 0; j--) {
			if (pleg[i]->cost < pleg[j]->cost) {
				int sig = 0;

				if (j == 0)
					sig = 1;
				else if (pleg[i]->cost >= pleg[j - 1]->cost)
					sig = 1;

				if (sig) {
					struct desk_leg *spleg = pleg[i];

					for (int t = i; t > j; t--) {
						pleg[t] = pleg[t - 1];
					}
					pleg[j] = spleg;
						
					break;
				}
			}
		}
	}
}

void sort_leg_by_len(struct desk_leg **pleg, int leg_num)
{
	for (int i = 1; i < leg_num; i++) {
		for (int j = i - 1; j >= 0; j--) {
			if (pleg[i]->len < pleg[j]->len) {
				int sig = 0;

				if (j == 0)
					sig = 1;
				else if (pleg[i]->len >= pleg[j - 1]->len)
					sig = 1;

				if (sig) {
					struct desk_leg *spleg = pleg[i];

					for (int t = i; t > j; t--) {
						pleg[t] = pleg[t - 1];
					}
					pleg[j] = spleg;

					break;
				}
			}
		}
	}
}

int classify_leg_by_len(struct desk *pdesk)
{
	
	for (int i = 0; i < pdesk->type_num; i++) {
		pdesk->sleg[i]->cost = pdesk->leg[i]->cost;
		pdesk->sleg[i]->len = pdesk->leg[i]->len;
	}

	for (int i = 0; i < pdesk->type_num; i++) {
		for (int j = i + 1; j < pdesk->type_num; j++) {
			if (pdesk->sleg[i]->len == pdesk->sleg[j]->len) {
				struct desk_leg *tleg = pdesk->sleg[j];

				pdesk->sleg[i]->num++;
				pdesk->sleg[i]->cost += pdesk->sleg[j]->cost;

				for (int t = j; t < pdesk->leg_num - 1; t++)
					pdesk->sleg[t] = pdesk->sleg[t + 1];

				pdesk->sleg[pdesk->leg_num - 1] = tleg;

				j--;
				pdesk->type_num--;
			}
		}
		
	}

	return 0;
}

int cost_repair_desk(struct desk *pdesk, int type)
{
	int count = pdesk->leg_num - pdesk->sleg[type]->num * 2 + 1;
	int sum = 0;
	struct desk_leg **pleg = pdesk->leg;

	for (int i = type + 1; i < pdesk->type_num; i++) {
		sum += pdesk->sleg[i]->cost;
		count -= pdesk->sleg[i]->num;
	}

	for (int i = 0; i < pdesk->leg_num && count > 0; i++) {
		if (pleg[i]->len < pdesk->sleg[type]->len) {
			sum += pdesk->leg[i]->cost;
			count--;
		}
	}

	return sum;
}

int get_desk_cost(struct desk *pdesk)
{
	int cost = cost_repair_desk(pdesk, 0);

	for (int i = 1; i < pdesk->type_num; i++) {
		int ret = cost_repair_desk(pdesk, i);
		if (cost > ret)
			cost = ret;
	}
		
	return cost;
}

int main(void)
{
	struct desk *pdesk = create_desk(LEG_NUM_MAX);
	int cost_total;
	DWORD time;

	if (pdesk == NULL)
		return -1;

	init_desk_for_test(pdesk);

	time = GetTickCount();

	sort_leg_by_cost(pdesk->leg, pdesk->leg_num);

	classify_leg_by_len(pdesk);

	sort_leg_by_len(pdesk->sleg, pdesk->type_num);

	cost_total = get_desk_cost(pdesk);

	time = GetTickCount() - time;

	show_desk_info(pdesk);

	printf("get the cost is %d, cost time is %d\n", cost_total, time);

	delete_desk(pdesk);

	while (1);

	return 0;
}

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧