Loading
NOIP2006普及組 明明的隨機數
NOIP2001提高組 一元三次方程求解

NOIP2004提高組 合併果子

Freddy posted @ 2011年10月08日 03:26 in NOIP with tags noip 貪心 c++ , 1471 阅读

【问题描述】
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。
每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
【输入文件】
输入文件fruit.in包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
【输出文件】
输出文件fruit.out包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。
【样例输入】
3
1 2 9
【样例输出】
15
【数据规模】

对于30%的数据,保证有n<=1000:
对于50%的数据,保证有n<=5000;
对于全部的数据,保证有n<=10000。

【分析】

貪心,每次找到最小的兩堆果子進行合併。

不要把本題看成石子歸併。

我用的是鏈表,全過了,但是速度較慢~

NOIP2004-fruit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <fstream>
using namespace std;   
ifstream fin("fruit.in");
ofstream fout("fruit.out");
class data
{
public:
    int key;
    //Other members HERE...
    int sen;//前驱
    int next;//后继
};
data A[200000];
int top;//链表中元素的个数
 
void Insert(int key)
{
    int point=0;
    while (key>A[point].key)
    {
        point=A[point].next;
    }
    //Create a new node
    A[top].key=key;
    A[top].next=point;
    A[top].sen=A[point].sen;
     
    A[point].sen=top;//后继的前驱等于自己
     
    A[A[top].sen].next=top;//前驱的后继等于自己
     
    top++;
}
 
void DeleteOne(int key)
{
    int point=A[0].next;
    while(A[point].next!=-1)
    {
        if(A[point].key==key)
        {
            A[A[point].sen].next=A[point].next; //自己前驱的后继等于自己的后继
            A[A[point].next].sen=A[point].sen;  //自己后继的前驱等于自己的前驱
            return; //跳出函数
        }
        point=A[point].next;
    }
}
 
void print()
{
    int point=A[0].next;
    while(A[point].next!=-1)
    {
        fout<<A[point].key<<endl;
        point=A[point].next;
    }
}
void debug()
{
    for (int i=0;i<top;i++)
        fout<<i<<" "<<A[i].key<<" "<<A[i].sen<<" "<<A[i].next<<endl;
}
 
int GetMinElem()
{
    int point=A[0].next;
    return A[point].key;
}
 
int main()
{
 
    //Initialize
    A[0].key=-1;A[0].next=1;A[0].sen=-1;
    A[1].key=0Xfffffff;A[1].next=-1;A[0].sen=0;
    top=2;
    int num,key;
    fin>>num;
    for (int i=0;i<num;i++)
    {
        fin>>key;
        Insert(key);//插入一个关键字
    }
     
    int liu=num;
    int cost=0;
    //debug();
    while (liu!=1)
    {
        int m=GetMinElem();
        DeleteOne(m);
        int n=GetMinElem();
        DeleteOne(n);
        //fout<<m<<" "<<n<<endl<<endl;
        cost+=(m+n);
        Insert(m+n);
        liu--;
    }
    //print();
    fout<<cost<<endl;
    return 0;
}

 

正在连接评测机...

 

已连接到评测机

GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty

正在编译...

编译成功

 

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 10 0.000 s 2614 KB 0
2 正确 10 0.002 s 2614 KB 0
3 正确 10 0.002 s 2614 KB 0
4 正确 10 0.043 s 2614 KB 0
5 正确 10 0.096 s 2614 KB 0
6 正确 10 0.403 s 2614 KB 0
7 正确 10 0.503 s 2614 KB 0
8 正确 10 0.396 s 2614 KB 0
9 正确 10 0.500 s 2614 KB 0
10 正确 10 0.508 s 2614 KB 0

运行完成

运行时间 2.453 s

平均内存使用 2614 KB

测试点通过状况 AAAAAAAAAA

得分:100

恭喜你通过了全部测试点!

 

Finance Essay Help U 说:
2018年12月14日 08:12

Incredible article! I am picking up from it. It's captivating and a marvellous substance. That is some extraordinary points of view with respect to this subject.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter