uva 10012 How Big Is It? (greedy + enumerate)

本文介绍了一道经典的算法题 UVA 10012 的解题思路,通过枚举和贪心算法求解将多个圆放置在矩形底部时矩形所需的最小长度。代码详细展示了如何计算不同圆排列下的矩形长度。

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=953

  这道题是比较简单的枚举加上贪心的题目,题意是将n个圆放进矩形内,要求圆要贴着矩形的底部,问矩形的长最小是多少。

  题目需要注意的是有可能有两个半径非常大的圆夹着两个半径非常小的圆的情况,除此之外,代码都很简单。

代码如下:

View Code
 1 #define REP(i, n) for (int i = 0; i < (n); i++)
 2 #define REP_1(i, n) for (int i = 1; i <= (n); i++)
 3 
 4 int idx[10];
 5 double R[10], pos[10];
 6 
 7 double cal(int n) {
 8     n--;
 9     pos[0] = 0.0;
10     REP_1(i, n) {
11         double tmp = -finf;
12         REP(j, i) {
13             tmp = max(tmp, pos[j] + sqrt(sqr(R[idx[i]] + R[idx[j]]) - sqr(R[idx[i]] - R[idx[j]])));
14         }
15         pos[i] = max(R[idx[i]] - R[idx[0]], tmp);
16     }
17     double ret = 0.0;
18     REP(i, n + 1) ret = max(ret, pos[i] + R[idx[i]]);
19     return R[idx[0]] + ret;
20 }
21 
22 double work(int n) {
23     double ret = finf;
24     REP(i, n) idx[i] = i;
25     do {
26         ret = min(ret, cal(n));
27     } while (next_permutation(idx, idx + n));
28     return ret;
29 }
30 
31 int main() {
32     int T, n;
33     scanf("%d", &T);
34     while (T-- && scanf("%d", &n)) {
35         REP(i, n) scanf("%lf", &R[i]);
36         printf("%.3f\n", work(n));
37     }
38     return 0;
39 }

 

——written by Lyon

转载于:https://www.cnblogs.com/LyonLys/archive/2013/02/25/uva_10012_Lyon.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值