Little Zu Chongzhi‘s Triangles 状压DP

链接

题意:

给你 n 个棍子长度,求用这些棍子所能组成的多个三角形的总面积最大值

解法:

用状压表示每根棍子的使用情况,最多12根棍子,那么最大的状态数为2^12-1,可用longlong保存

若状态数二进制为 i =1001001(2),则表示第1,4,7根棍子已经使用,故后面不能再使用

dp[i] 表示 状态数 i 中剩下的棍子中所能取得的最大总三角形面积值 

然后暴力递归记忆化即可

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int a[20];
int n;
int now=0;
double dp[1000006];
double dfs(int now)
{
	if(dp[now]!=-1) return dp[now];
	double ans=0;
	for(int i=0;i<n;i++)
	{
		if((now>>i) %2) continue;
		for(int j=i+1;j<n;j++)
		{
			if((now>>j) %2) continue;
			for(int k=j+1;k<n;k++)
			{
				if((now>>k) %2) continue;
				int aa=(now>>i) %2;
				int bb=(now>>j)% 2;
				int cc=(now>>k)% 2;
				int nnow=now;
				if(aa+bb+cc==0) 
				{					
					nnow|=(1<<i);
					nnow|=(1<<j);
					nnow|=(1<<k);
					aa=a[i];
					bb=a[j];
					cc=a[k];
					int b[4];
					b[0]=aa;
					b[1]=bb;
					b[2]=cc;
					sort(b,b+3);
					if(b[0]+b[1]<=b[2]) continue;
					aa=b[0];
					bb=b[1];
					cc=b[2];
					double p=(aa+bb+cc)/2.0;
					double s=sqrt(p*(p-aa)*(p-bb)*(p-cc));
					ans=max(ans,s+dfs(nnow));
				}
				else continue;
			}
		}
	}
	dp[now]=ans;
	return ans;
}
int main()
{
	while(~scanf("%d",&n)&&n)
	{
		for(int i=0;i<=1e6;i++) dp[i]=-1;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
		double ans=0;
		ans=dfs(0);
		printf("%.2lf\n",ans);
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值