POJ - 2686
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=10;
const int maxm=35;
const int INF=1<<29;
int n,m,a,b,p;
double ans;
double t[maxn];
double mz[maxm][maxm];
double dp[1<<maxn][maxm];
void DP()
{
for(int s=(1<<n)-1;s>=0;s--)
{
for(int v=1;v<=m;v++)
for(int i=0;i<n;i++)
{
if((s>>i)&1)
{
for(int u=1;u<=m;u++)
if(mz[v][u]>=0)
dp[s&~(1<<i)][u]=min(dp[s&~(1<<i)][u],dp[s][v]+mz[v][u]/t[i]);
}
}
}
}
int main()
{
while(cin>>n>>m>>p>>a>>b)
{
if(n==0&&m==0&&p==0&&a==0&&b==0) break;
memset(mz,-1,sizeof(mz));
for(int i=0;i<(1<<n);i++)
fill(dp[i],dp[i]+m+1,INF);
ans=INF;
for(int i=0;i<n;i++)
cin>>t[i];
for(int i=0;i<p;i++)
{
int x,y;
cin>>x>>y;
cin>>mz[x][y];
mz[y][x]=mz[x][y];
}
dp[(1<<n)-1][a]=0;
DP();
for(int i=0;i<(1<<n);i++)
ans=min(ans,dp[i][b]);
if(ans==INF)
cout<<"Impossible"<<endl;
else cout<<ans<<endl;
}
return 0;
}
POJ - 2441
#include<iostream>
#include<string.h>
using namespace std;
typedef long long ll;
const int maxn=21;
const int maxm=21;
const int INF=1<<29;
int n,m,ans;
int mz[maxm][maxm];
int dp[1<<maxm];
void DP()
{
for(int i=0;i<n;i++)
{
for(int s=(1<<m)-1;s>=0;s--)
{
if(!dp[s]) continue;
for(int j=0;j<m;j++)
{
if(s&(1<<j)) continue;
if(mz[i+1][j]==0)continue;
dp[s|(1<<j)]+=dp[s];
}
dp[s]=0;
}
}
}
int main()
{
while(cin>>n>>m)
{
memset(mz,0,sizeof(mz));
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
{
int k,temp;
cin>>k;
for(int j=0;j<k;j++)
{
cin>>temp;
temp--;
mz[i+1][temp]=1;
}
}
dp[0]=1;
DP();
ans=0;
for(int i=0;i<(1<<m);i++)
ans+=dp[i];
cout<<ans<<endl;
}
return 0;
}
POJ - 3254
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=15;
const int maxm=15;
const int mod=1e8;
const int INF=1<<29;
int n,m,ans;
int mz[maxm][maxm];
int v[1<<maxn];
int dp[maxm][1<<maxm];
void init()//筛选出不相邻的状态
{
int cnt=0;
for(int i=0;i<(1<<maxn);i++)
{
if(!(i&(i<<1)))
v[cnt++]=i;
}
}
int C(int x,int y)
{
for(int i=0;i<n;i++)
if((y&(1<<i))&&!mz[x][i])
return 1;
return 0;
}
void DP()
{
for(int i=0;i<m;i++)
{
for(int s=0;v[s]<(1<<n);s++)
{
if(C(i,v[s])) continue;
if(i==0) {dp[i][s]=1; continue;}
for(int j=0;v[j]<(1<<n);j++)
{
if((v[j]&v[s])==0)
dp[i][s]+=dp[i-1][j];
}
}
}
}
int main()
{
init();
while(cin>>m>>n)
{
memset(mz,0,sizeof(mz));
memset(dp,0,sizeof(dp));
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
cin>>mz[i][j];
DP();
ans=0;
for(int i=0;v[i]<(1<<n);i++)
ans=(ans+dp[m-1][i])%mod;
cout<<ans<<endl;
}
return 0;
}
POJ - 2836
#include<iostream>
#include<string.h>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=16;
int n,m,ans,cnt;
int dp[1<<maxn];
int x[maxn],y[maxn],S[maxn*maxn];
int cover[maxn*maxn];
void init()
{
cnt=0;
for(int i=1;i<n;i++)
for(int j=0;j<i;j++)
{
int w=abs(x[i]-x[j]);
int h=abs(y[i]-y[j]);
if(w==0) w=1; //可能会存在x/y相同的情况,记得处理,不然面积就变成0了orz
if(h==0) h=1;
S[cnt]=w*h;
cover[cnt]=0;
for(int k=0;k<n;k++)
{
if(x[k]>=min(x[i],x[j])&&x[k]<=max(x[i],x[j])&&
y[k]>=min(y[i],y[j])&&y[k]<=max(y[i],y[j]))
cover[cnt]|=(1<<k);
}
cnt++;
}
}
void DP()
{
dp[0]=0;
for(int s=0;s<(1<<n);s++)
{
if(dp[s]!=0x3f)
for(int j=0;j<cnt;j++)
{
int temp=s|cover[j];
if(temp!=s)
dp[temp]=min(dp[temp],dp[s]+S[j]);
}
}
}
int main()
{
while(cin>>n&&n)
{
memset(dp,0x3f,sizeof(dp));
for(int i=0;i<n;i++)
cin>>x[i]>>y[i];
init();
DP();
cout<<dp[(1<<n)-1]<<endl;
}
return 0;
}