poj2288

    xiaoxiao2025-11-07  4

    poj2288

    TIP: 注意分析好状态,这里用一个三维的数组表示,注意要另外开一个num数组。 n=1时候要注意特判。

    #include<cstdio> #include<vector> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int n,m; ll v[20]; int mp[20][20]; ll val,cnt; ll dp[1<<13][20][20]; ll num[1<<13][20][20]; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { scanf("%lld",&v[i]); } memset(mp,0,sizeof mp); // for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { int a,b,c; scanf("%d%d",&a,&b); a--; b--; mp[a][b]=mp[b][a]=1; } } if(n==1) { printf("%lld 1\n",v[0]); continue; } memset(num,0,sizeof num); memset(dp,-1,sizeof dp); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(i!=j&&mp[i][j]) { dp[(1<<i)+(1<<j)][i][j]=v[i]*v[j]+v[i]+v[j]; num[(1<<i)+(1<<j)][i][j]=1; } } } for(int i=0;i<(1<<n);i++) { for(int j=0;j<n;j++) { if(i&(1<<j)) for(int k=0;k<n;k++) { if((i&(1<<k))&&(mp[j][k])&&j!=k) for(int t=0;t<n;t++) { if(i&(1<<t)) continue; if(j!=t&&k!=t&&mp[k][t]) { int ne=i+(1<<t); if(dp[i][j][k]==-1) continue; int tmp=dp[i][j][k]+v[k]*v[t]+v[t]; if(mp[j][t]) { tmp+=v[t]*v[j]*v[k]; } if(tmp>dp[ne][k][t]) { dp[ne][k][t]=tmp; num[ne][k][t]=num[i][j][k]; } else if(tmp==dp[ne][k][t]) { num[ne][k][t]+=num[i] [j][k]; } } } } } } val=-1; cnt=0; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(i==j) continue; if(dp[(1<<n)-1][i][j]>val) { val=dp[(1<<n)-1][i][j]; cnt=num[(1<<n)-1][i][j]; } else if(val==dp[(1<<n)-1][i][j]) { cnt+=(num[(1<<n)-1][i][j]); } } } if(val!=-1) printf("%lld %lld\n",val,cnt/2); else puts("0 0"); } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-1303927.html
    最新回复(0)