2014校选题(四)-- 贪心问题
2014-04-24 09:14
417 查看
题目四
【问题描述】
在一个果园里,张三已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。张三决定把所有的果子合成一堆。
每一次合并,张三可以把两队果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。张三在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使张三耗费的体力最少,并输出这个最小的体力耗费值。
假如有3种果子,数目依次为1,2,9,可以先将1、2堆合并,数目为12,耗费体力为12。所以张三总共消耗体力=3+12=15。可以证明15为最小的体力耗费值。
【输入】
输入包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
【输出】
输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231
【样例输入】
3
1 2 9
【样例输出】
15
///思路用链表将值从小到大排列,每次最小的两个值相加
/***********************
*
* title: 贪心问题
*
* time: 2014.4.24
*
***********************/
/*
联系实际:
现实生活中,搬运越重的物品越少次越省力气。
*/
//思路用链表将值从小到大排列
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
//构造链表结构
typedef struct Node
{
ElemType data;
struct Node* next;
} Node, *LinkList;
ElemType num; //全局变量 得到最后体力值
//初始化链表,并从小到大排序
void CreateList(LinkList *L, int n)
{
void Insert(LinkList L, ElemType data);
int i;
int data;
*L = (LinkList)malloc(sizeof(Node)); //头结点
(*L)->next = NULL;
num = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &data);
Insert(*L, data);
}
}
//按从小到大,插入data值
void Insert(LinkList L, ElemType data)
{
LinkList p; //当前结点
LinkList pre; //当前位置的前一结点
LinkList s;
p = L->next;
pre = L;
while (p != NULL)
{
if (p->data > data)
{
s = (LinkList)malloc(sizeof(Node));
s->next = p;
pre->next = s;
s->data = data;
break;
}
pre = p;
p = p->next;
}
if (p == NULL)
{
s = (LinkList)malloc(sizeof(Node));
pre->next = s;
s->next = NULL;
s->data = data;
}
return 0;
}
//将前两个node值相加充当返回值,并删除这两个node
ElemType Delete(LinkList L)
{
ElemType a = 0;
LinkList p;
if (L->next->next != NULL) //如果有2个node
{
p = L->next;
a = p->data;
a += p->next->data;
L->next = p->next->next;
free(p->next);
free(p);
}
else //如果只有1个node
{
a = L->next->data;
free(L->next);
L->next = NULL;
}
num += a;
return a;
}
void PrintSearch(LinkList L)
{
ElemType e;
if (L->next != NULL) //防止 n == 0 情况
{
e = Delete(L);
}
while (L->next != NULL) //如果有值
{
Insert(L, e);
e = Delete(L);
}
printf("%d\n", num);
}
int main()
{
int n;
LinkList L;
while (~scanf("%d", &n))
{
CreateList(&L, n);
PrintSearch(L);
}
return 0;
}
【问题描述】
在一个果园里,张三已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。张三决定把所有的果子合成一堆。
每一次合并,张三可以把两队果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。张三在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使张三耗费的体力最少,并输出这个最小的体力耗费值。
假如有3种果子,数目依次为1,2,9,可以先将1、2堆合并,数目为12,耗费体力为12。所以张三总共消耗体力=3+12=15。可以证明15为最小的体力耗费值。
【输入】
输入包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
【输出】
输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231
【样例输入】
3
1 2 9
【样例输出】
15
///思路用链表将值从小到大排列,每次最小的两个值相加
/***********************
*
* title: 贪心问题
*
* time: 2014.4.24
*
***********************/
/*
联系实际:
现实生活中,搬运越重的物品越少次越省力气。
*/
//思路用链表将值从小到大排列
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
//构造链表结构
typedef struct Node
{
ElemType data;
struct Node* next;
} Node, *LinkList;
ElemType num; //全局变量 得到最后体力值
//初始化链表,并从小到大排序
void CreateList(LinkList *L, int n)
{
void Insert(LinkList L, ElemType data);
int i;
int data;
*L = (LinkList)malloc(sizeof(Node)); //头结点
(*L)->next = NULL;
num = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &data);
Insert(*L, data);
}
}
//按从小到大,插入data值
void Insert(LinkList L, ElemType data)
{
LinkList p; //当前结点
LinkList pre; //当前位置的前一结点
LinkList s;
p = L->next;
pre = L;
while (p != NULL)
{
if (p->data > data)
{
s = (LinkList)malloc(sizeof(Node));
s->next = p;
pre->next = s;
s->data = data;
break;
}
pre = p;
p = p->next;
}
if (p == NULL)
{
s = (LinkList)malloc(sizeof(Node));
pre->next = s;
s->next = NULL;
s->data = data;
}
return 0;
}
//将前两个node值相加充当返回值,并删除这两个node
ElemType Delete(LinkList L)
{
ElemType a = 0;
LinkList p;
if (L->next->next != NULL) //如果有2个node
{
p = L->next;
a = p->data;
a += p->next->data;
L->next = p->next->next;
free(p->next);
free(p);
}
else //如果只有1个node
{
a = L->next->data;
free(L->next);
L->next = NULL;
}
num += a;
return a;
}
void PrintSearch(LinkList L)
{
ElemType e;
if (L->next != NULL) //防止 n == 0 情况
{
e = Delete(L);
}
while (L->next != NULL) //如果有值
{
Insert(L, e);
e = Delete(L);
}
printf("%d\n", num);
}
int main()
{
int n;
LinkList L;
while (~scanf("%d", &n))
{
CreateList(&L, n);
PrintSearch(L);
}
return 0;
}
相关文章推荐
- 2014校选题(三)-- 字符串问题
- 树规+贪心 问题 B: [Poi2014]FarmCraft
- 2014校选题(二)-- 母函数问题
- 贪心-nyoj-过河问题
- hdu-4864 Task 2014多校联赛第一场 贪心
- 部分背包问题的贪心算法正确性证明
- 总结#2----一类贪心问题
- NYOJ 106 背包问题(贪心,经典题目)
- nyoj 过河问题 贪心
- SQL server 2014安装以及解决连接数据库失败问题
- 贪心算法作业之会场安排问题
- ZOJ3953 Intervals 【贪心 双线程活动分配问题】
- 解决NLPIR-ICTCLAS2014分词系统词库过大,造成读取缓慢问题
- AYITACM2016省赛第三周A-Nested Dolls(贪心解嵌套问题)
- NYOJ-106 背包问题(贪心)
- codeforces 460 C Present 二分+贪心 最大化最小值问题
- BZOJ 3671 [Noi 2014] 贪心 解题报告
- 【贪心】删数问题
- 2014阿里巴巴秋季校园招聘-软件研发工程师笔试题/面试问题收集
- 贪心--会场安排问题