http://acm.hdu.edu.cn/showproblem.php?pid=5135
题意:给你N个木棍的长度,然后让你组成三角形,问你组成的三角形的和最大是多少?
思路:先求出可以组成的所有的三角形,然后状压dp就可以。求所有的三角形也可以用状压,也可以三重循环求。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 1<<13
using namespace std; int n;
int a[];
int b[];
int cc[maxn];
double ss[maxn];
double ans;
double dp[maxn]; bool vis[]; int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==) break;
memset(cc,,sizeof(cc));
memset(dp,,sizeof(dp));
memset(ss,,sizeof(ss));
for(int i=; i<n; i++)
{
scanf("%d",&a[i]);
}
int t1=;
for(int i=; i<(<<n); i++)
{
memset(b,,sizeof(b));
int cnt=;
for(int j=; j<n; j++)
{
if((<<j)&i) cnt++;
}
if(cnt==)
{
int c=;
for(int j=; j<n; j++)
{
if((<<j)&i)
{
b[c++]=a[j];
}
}
if((b[]<b[]+b[])&&(b[]<b[]+b[])&&(b[]<b[]+b[]))
{
cc[t1]=i;
double p=(double)((b[]+b[]+b[])*1.0/);
double s=sqrt(p*(p-b[]*1.0)*(p-b[]*1.0)*(p-b[]*1.0));
ss[t1++]=s;
}
}
}
double ans=;
for(int i=; i<(<<n); i++)
{
for(int j=; j<t1; j++)
{
if((i&(cc[j]))==)
{
dp[i|cc[j]]=max(dp[i|cc[j]],dp[i]+ss[j]);
ans=max(ans,dp[i|cc[j]]);
}
}
}
printf("%.2lf\n",ans);
}
return ;
}