标签:input 无法 names check base 直接 规模 bool 输入格式
和所有人一样,奶牛喜欢变化。它们正在设想新造型的牧场。奶牛建筑师 Hei 想建造围有漂亮白色栅栏的三角形牧场。她拥有 nn 块木板,每块的长度 l_ili? 都是整数,她想用所有的木板围成一个三角形使得牧场面积最大。
请帮助 Hei 小姐构造这样的牧场,并计算出这个最大牧场的面积。
第 11 行:一个整数 n;
第 22 到第 (n + 1)行,每行一个整数,第 (i+1) 行的整数li? 表示第 i 块木板的长度。
仅一个整数:最大牧场面积乘以 100100 然后舍尾的结果。如果无法构建,输出 -1。
5 1 1 3 3 4
692
692=\text{舍尾后的}(100\times\text{三角形面积})692=舍尾后的(100×三角形面积),此三角形为等边三角形,边长为 44。
对于 100\%100% 的数据,保证 3\le n\le403≤n≤40,1\le l_i\le401≤li?≤40
解析:
这是比较典型的01背包问题:
(1)首先定义状态
f[k][i][j]:前K调表是否恰好组成长分别为i和j的栅栏,是1,否0;
则f[k][i][j]=f[k-1][i-a[k]][j]//第k条边装在栅栏i
f[k-1][i][j-a[k]]//第k条边装在栅栏j
f[k-1][i][j]//第k条边装在第三条栅栏
#include<iostream>
//#include<>
#include<cmath>
using namespace std;
const int maxn=50;
int f[900][900],a[maxn];
int n,tot=0;
double ans=-1;
bool Check(int x,int y){
int z=tot-x-y;
return (x+y>z&&x+z>y&&y+z>x);
}
double Cal(int x,int y){
int z=tot-x-y;
double p=(x+y+z)/2.0;//整数/整数 =整数
return sqrt(p*(p-x)*(p-y)*(p-z));
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) {cin>>a[i];tot+=a[i];}
int t=tot/2;
f[0][0]=1;
// for(int i=1;i<=n;i++)f[a[i]][0]=f[0][a[i]]=1;
f[a[1]][0]=f[0][a[1]]=1;//第一条边,直接赋值
for(int k=2;k<=n;k++)
for(int i=t;i>=1;i--)
for(int j=t;j>=1;j--){
if(i>=a[k])f[i][j]|=f[i-a[k]][j];
if(j>=a[k])f[i][j]|=f[i][j-a[k]];
}
for(int i=1;i<=t;i++){
for(int j=1;j<=t;j++){
if(f[i][j]&&Check(i,j))ans=max(ans,Cal(i,j));
// cout<<i<<" "<<j<<" "<<tot-i-j<<" "<<f[i][j]<<" "<<ans<<endl;
}
}
if(ans>0)cout<<(int)(ans*100)<<endl;
else cout<<ans<<endl;
return 0;
}
标签:input 无法 names check base 直接 规模 bool 输入格式
原文地址:https://www.cnblogs.com/ssfzmfy/p/12825759.html