题目(保护羊村):
【题目描述】
伟大的Yyz 帮助羊羊们逃出了城堡,可Jack 自然不会善罢甘休。“我会诅咒你们的!”杰杰恼羞成怒地喊道。回到羊村后,羊羊们发现羊村地震了。看来Jack的诅咒生效了。当务之急是修补因地震而坍塌的围墙。
围墙上有n 个圆形洞。第i 个洞的直径是d_i 米,修复第i 个洞的时间是t_i 分钟,一个洞开始修就必须修完。不妙的是,据可靠情报,灰太狼在c 分钟后就将袭击羊村,你的任务当然是使灰太狼来时剩余洞的总面积最小,以便羊羊们在灰太狼来时能够更好的防御。
【输入】
第1 行,一个正整数n,表示洞的总数。
第2~n+1 行,每行有2 个正整数d_i 和t_i(d_i,n_i≤10,000),d_i 表示 第i 个洞的直径,t_i 表示修复第i 个洞的时间。
第n+2 行,一个正整数c(c≤1,000,000),表示灰太狼将在c 分钟后到来。
【输出】
输出一行一个实数s,表示灰太狼来时剩余洞的最小面积。
π取3.1416,最后结果保留4 位小数。
【样例输入】
4
4 1
6 2
12 3
7 2
6
【样例输出】
28.2744
【数据范围】
80%的数据满足:1≤n≤15;
100%的数据满足:1≤n≤100
分析:
显然是一道背包DP(别问我为什么写挂了)
把洞看成物体,时间看成体积,洞的面积看成价值,这,就是一道01背包求最大价值。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 120
int n,t[N],c;
double dp[1000100],pi=3.1416,ans,ans1,d[N],w[N];
double area(double r){
double ans=r*r*pi;
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lf%d",&d[i],&t[i]);
ans1+=area(d[i]/2.0);
w[i]=area(d[i]/2.0);
}
scanf("%d",&c);
for(int i=1;i<=n;i++)
for(int j=c;j>=t[i];j--)
dp[j]=max(dp[j],dp[j-t[i]]+w[i]);//标准背包模板
printf("%.4lf",ans1-dp[c]);//总价值减最大价值
return 0;
}