校赛热身 Problem C. Sometimes Naive (状压dp)
2018-03-17 21:52
357 查看
题解:
列举每一种3的倍数的组合,开始先求出3条边的可行解,则
六条边的可行解可以由两个三条边得来。
代码:
#include<bits/stdc++.h>
using namespace std;
int a[22],n,cnt,ant,is[500007],dp[1050007];
struct node
{
int num,id;
}angle[500007];
bool cmp(const node& a,const node& b)
{
return a.num<b.num;
}
int abs1(int x)
{
if(x<0)return -x;
return x;
}
void init()
{
for(int i=0;i<(1<<n);i++)
{
int ans=0,t=i;
while(t)
{
if(t&1)ans++;
t=t>>1;
}
if(ans%3==0)
{
angle[cnt].id=i;
angle[cnt++].num=ans/3;
}
if(ans==3)
{
int v[4],ans1=0,ans2=0,t=i;
while(t)
{
if(t&1)v[ans1++]=a[ans2];
t=t>>1;
ans2++;
}
if(abs1(v[1]-v[2])<v[0]&&abs1(v[1]-v[0])<v[2]&&abs1(v[2]-v[0])<v[1])
{
is[ant++]=i;
dp[i]=1;
}
}
}
}
int main()
{
int T,cas=0;scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
cnt=0,ant=0;
memset(dp,0,sizeof(dp));
dp[0]=1;
init();
sort(angle,angle+cnt,cmp);
for(int i=0;i<cnt;i++)
{
node e=angle[i];
for(int j=0;j<ant;j++)
{
if(dp[e.id]&&!(e.id&is[j]))//若e.id已存在并且
//.e.id中的边与is[j]中没有重边则dp[e.id|is[j]]=1
dp[e.id|is[j]]=1;
}
}
for(int i=cnt-1;i>=0;i--)
{
if(dp[angle[i].id])
{
printf("Case #%d: %d\n",++cas,angle[i].num);
break;
}
}
}
return 0;
}
相关文章推荐
- ZOJ 3777 Problem Arrangement (状压DP)
- TopCoder SRM 672 Div2 Problem 1000 - Tdetectived2 (状压dp)
- FZU-2218 Simple String Problem(状压DP)
- FZU2218 Simple String Problem--状压dp
- FZU2218 Simple String Problem(状压DP)
- FZU 2218 Simple String Problem(状压DP)
- ZOJ 3777 - Problem Arrangement(状压DP)
- TopCoder SRM 663 Div2 Problem 1000 - CheeseRolling (状压dp)
- ZOJ 3777-Problem Arrangement(状压DP)
- FZU 2218 Simple String Problem(状压DP)
- ZOJ 3777 Problem Arrangement(状压DP)
- 【ZOJ3777】Problem Arrangement(状压dp)
- 校赛热身 Problem D. Unsolved Mystery
- TopCoder SRM 667 Div1 Problem 250 - OrderOfOperations (状压dp)
- ZOJ-3777-Problem Arrangement(状压DP)
- CSU-1964 Problem_hc(状压dp)
- 2014 Super Training #4 B Problem Arrangement --状压DP
- FZU 2218 Simple String Problem (状压DP解决集合不相同元素问题)
- Simple String Problem FZU - 2218 状压dp
- 2015广东工业大学ACM校赛 I 游戏王 (状压dp)