维修栅栏(fence)
原题搁这
描述
小晶晶最近当上了农场主!不过,还没有来得及庆祝,一件棘手的问题就摆在了小晶晶的面前。农场的栅栏,由于年久失修,出现了多处破损。栅栏是由n块木板组成的,每块木板可能已经损坏也可能没有损坏。小晶晶知道,维修连续m个木板(这m个木板不一定都是损坏的)的费用是sqrt(m)。可是,怎样设计方案才能使总费用最低呢?小晶晶想请你帮帮忙。
输入
第一行包含一个整数n,表示栅栏的长度;
第二行包含n个由空格分开的整数(长整型范围内)。如果第i个数字是0,则表示第i块木板已经损坏,否则表示没有损坏。
输出
仅包含一个实数,表示最小维修费用;注意:答案精确到小数点后3位。
输入样例 1
9 0 –1 0 1 2 3 0 –2 0
输出样例 1
3.000
提示
30%的数据中,n≤20;
100%的数据中,n≤2500。
来源 聪明人的游戏
解决这道题
这道题我们很明显可以来解决。
So我们就要对这堆栅栏进行分类讨论, 假设我们修到了第i个帐篷,那么就有以下几种可能:
(1) 这个帐篷本来就是好的;
(2) 这个帐篷不是好的;
对于(1)来说,我们不用修,直接就是
对于(2)来说,我们要修,怎么修——选最少的修。所以我们枚举一下
单独修
两个两个修
三个三个修
.............
全都一起修
So
.............
选最小的就好了。
完整代码:
#include<bits/stdc++.h>
using namespace std;
int n,a[3000];
double dp[3000];
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
dp[i]=2147483647;
for(int i=1;i<=n;i++) {
if(!a[i]) {
for(int j=1;j<=i;j++)
dp[i]=min(dp[i-j]+sqrt(j),dp[i]);
}else
dp[i]=dp[i-1];
}
printf("%.3lf",dp[n]);
return 0;
}

浙公网安备 33010602011771号