1. 程式人生 > >NOIP提高組 積木

NOIP提高組 積木

Description

這裡寫圖片描述

Data Constraint

這裡寫圖片描述

Solution

對於這種題我們考慮用狀態壓縮dp來做。我們設出f[i][j][k]表示現在的二進位制狀態為i(表示選了哪些數),當前最頂層的積木為j,積木j的擺放狀態k(k為1、2、3)。然後直接轉移即可。

程式碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define sqr(x) ((x)*(x))
#define ln(x,y) int(log(x)/log(y)) using namespace std; const char* fin="aP2.in"; const char* fout="aP2.out"; const int inf=0x7fffffff; const int maxn=17,maxk=1<<maxn; const int w[3][3]={{0,1,2},{0,2,1},{1,2,0}}; int n,i,j,k,l,o; int a[maxn][3]; ll f[maxk][maxn][3]; ll ans; int main(){ scanf("%d"
,&n); for (i=1;i<=n;i++){ scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]); sort(a[i],a[i]+3); } for (i=0;i<1<<n;i++) for (j=1;j<=n;j++) for (k=0;k<3;k++){ if (i==((1<<n)-1)) continue; for (l=1
;l<=n;l++){ if (i&(1<<(l-1))) continue; for (o=0;o<3;o++){ if (a[l][w[o][0]]<=a[j][w[k][0]] && a[l][w[o][1]]<=a[j][w[k][1]]){ f[i|(1<<(l-1))][l][o]=max(f[i][j][k]+a[l][w[o][2]],f[i|(1<<(l-1))][l][o]); ans=max(ans,f[i|(1<<(l-1))][l][o]); } } } } printf("%lld",ans); return 0; }