| Time Limit: 4000MS | Memory Limit: 65536K | |
| Total Submissions: 8845 | Accepted: 2296 |
Description
Input
Output
Sample Input
2 3 3 2 2 2 1 2 2 3 3 1 4 6 1 2 3 4 1 2 1 3 1 4 2 3 2 4 3 4
Sample Output
22 3 69 1
Source
#include<stdio.h>
#include<string.h>
#define FOR(i,l,r) for(i=l;i<=r;i++)
#define mulit(j) (1<<j)
typedef struct nnn
{
__int64 sum,k;
}node;
node dp[mulit(13)+5][14][14];
int map[14][14];
__int64 v[14];
int main()
{
int t,n,m,a,b,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
FOR(i,0,mulit(n)-1)//初始化
FOR(j,0,n-1)
for(int e=0;e<n;e++)
dp[i][j][e].sum=-1;
memset(map,0,sizeof(map));
FOR(i,0,n-1)
scanf("%I64d",&v[i]);
while(m--)
{
scanf("%d%d",&a,&b); a--,b--;
map[a][b]=map[b][a]=1;
}
if(n==1)
{
printf("%I64d %d\n",v[0],1); continue;
}
for( i=0;i<n;i++)//处理两个点的状态
for( j=i+1;j<n;j++)
if(map[i][j])
{
int state=mulit(i)+mulit(j);
dp[state][i][j].sum=dp[state][j][i].sum=v[i]+v[j]+v[i]*v[j];
dp[state][i][j].k=dp[state][j][i].k=1;
}
for(int state=1;state<mulit(n);state++)//枚举状态,处理两个点以上
for( j=0;mulit(j)<=state;j++)//状态以j点结尾
if(state&mulit(j))
for( i=0;mulit(i)<=state;i++)//状态结尾点j的前一个点i,从i--->j.
if(i!=j&&(mulit(i)&state))
{
if(dp[state][i][j].sum==-1)continue;//没有该状态是从i--->j,以j为结尾点的状态
for(int e=0; e<n; e++)//找到一个点e,存在从j--->e,e没有走过,不在该状态
if((mulit(e)&state)==0&&map[j][e])
{
int tstat=state+mulit(e),ss=0;
if(map[i][e])//状态tstat以i,j,e三点结尾的可以形成三角形
ss=v[i]*v[j]*v[e];
if(dp[tstat][j][e].sum<dp[state][i][j].sum+v[e]+v[j]*v[e]+ss)//更新
{
dp[tstat][j][e].sum=dp[state][i][j].sum+v[e]+v[j]*v[e]+ss;
dp[tstat][j][e].k=dp[state][i][j].k;
}
else if(dp[tstat][j][e].sum==dp[state][i][j].sum+v[e]+v[j]*v[e]+ss)
dp[tstat][j][e].k+=dp[state][i][j].k;
}
}
__int64 maxsum=-1,k=0;
for(i=0; i<n;i++)
for(j=0;j<n;j++)
if(i!=j&&dp[mulit(n)-1][i][j].sum!=-1)
{
if(dp[mulit(n)-1][i][j].sum>maxsum)
{
maxsum=dp[mulit(n)-1][i][j].sum;
k=dp[mulit(n)-1][i][j].k;
}
else if(dp[mulit(n)-1][i][j].sum==maxsum)
k+=dp[mulit(n)-1][i][j].k;
}
if(maxsum==-1)maxsum=0;//没有把所有的点只走一次就能全部点都走到
printf("%I64d %I64d\n",maxsum,k/2);
/* k/2是因为:假设有4个点,最大走法是3-->1-->4-->2,那么2-->4-->1-->3也是最大走法,
但走法都是算一条走法,因为路的条数和走的方向没有关系。
*/
}
}
POJ2288Islands and Bridges(状态压缩DP,求最大路和走条数),布布扣,bubuko.com
POJ2288Islands and Bridges(状态压缩DP,求最大路和走条数)
原文地址:http://blog.csdn.net/u010372095/article/details/38493747