状压DP(挑战程序设计竞赛)
#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; }
#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; }
#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; }
#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; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步