hdu3001 三进制 状态压缩dp

来源:互联网 发布:qt sqlserver 编辑:程序博客网 时间:2024/06/11 18:56

转自:

http://blog.csdn.net/u011721440/article/details/39738173



都过了这么久了。。。我连这么基础的状态压缩dp都不会。。

收获:

(1)没有关于树这种说法中。。要记得注意重边,,,

(2)原来的多进制是这样弄得。。

(3)他这里更新答案的时候是怎样更新的。

#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<string>#include<cstring>#include<iomanip>#include<iostream>#include<stack>#include<cmath>#include<map>#include<vector>#define ll long long#define INF 1000000000#define bug1 cout<<"bug1"<<endl;#define bug2 cout<<"bug2"<<endl;#define bug3 cout<<"bug3"<<endl;using namespace std;#define sf scanf#define pf printf#define mem(a,b) memset(a,b,sizeof(a));const int inf=0x1f1f1f1f;//2017年4月20日21:54:16const int maxx=60000;int e[12][12];int n,m;int tri[12];int dig[maxx][12];int dp[maxx][12];void init(){    tri[1]=1;    for(int i=2;i<=11;++i){        tri[i]=tri[i-1]*3;    }    for(int i=1;i<=tri[11];++i){        int t=i;        for(int j=1;j<=10;++j){            dig[i][j]=t%3;            t/=3;            if(t==0)break;        }    }}int main(){    init();    while(~sf("%d%d",&n,&m)){            int ans=inf;        mem(e,inf);        mem(dp,inf);        for(int i=1;i<=m;++i){            int u,v,c;            sf("%d%d%d",&u,&v,&c);            e[u][v]=e[v][u]=min(c,e[v][u]);        }        for(int i=1;i<=n;++i){            dp[tri[i]][i]=0;        }        for(int s=1;s<tri[n+1];++s){            int fg=1;            for(int i=1;i<=n;++i){                if(dig[s][i]==0) fg=0;                if(dp[s][i]==inf)continue;                for(int j=1;j<=n;++j){                    if(j==i||dig[s][j]>=2||e[i][j]==inf)continue;                    int v=s+tri[j];                    dp[v][j]=min(dp[v][j],dp[s][i]+e[i][j]);                }            }            if(fg){                for(int i=1;i<=n;++i){                    ans=min(ans,dp[s][i]);                }            }        }        if(ans==inf)ans=-1;        pf("%d\n",ans);    }}

2017年5月6日09:25:11;

自己再做,还是有错。。  至少知道了多进制不能<<

#include<iostream>#include<string>#include<cmath>#include<cstring>#include<algorithm>#include<cstdio>#include<iomanip>#include<queue>#include<map>#include<set>using namespace std;#define mem(a,b) memset(a,b,sizeof(a));#define sf scanf#define pf printfconst int INF=1e9;const int N=15;const int M=60000;const int inf=0x3f3f3f3f;int n,m;//2017年5月6日08:42:30int g[N][N];int p[15];int dig[M][11];int d[M][11];void init(){    for(int i=0;i<=p[11];++i){        int cnt=0;        int t=i;        for(int j=1;j<=10;++j){            dig[i][j]=t%3;            t/=3;            if(t==0)break;        }    }}int main(){    p[1]=1;//自己一开始把p[0]=1;,这是不对的。。    for(int i=2;i<=11;++i){        p[i]=p[i-1]*3;    }    init();    while(~sf("%d%d",&n,&m)){        mem(g,inf);mem(d,inf);        for(int i=1;i<=n;++i)d[p[i]][i]=0;        for(int i=1;i<=m;++i){            int u,v,c;            sf("%d%d%d",&u,&v,&c);            g[u][v]=g[v][u]=min(g[v][u],c);        }        int ans=INF;        for(int i=1;i<p[n+1];++i){            int flag=1;            for(int j=1;j<=n;++j){                if(dig[i][j]==0){                    flag=0;                }                if(d[i][j]==inf)continue;                for(int v=1;v<=n;++v){                    if(v!=j&&g[j][v]!=inf&&dig[i][v]<2){//注意三进制和二进制不同,,别用<<                        //d[i+(1<<(v-1))][v]=min(d[i+(1<<(v-1))][v],d[i][j]+g[j][v]);                        d[i+p[v]][v]=min(d[i+p[v]][v],d[i][j]+g[j][v]);                    }                }            }            if(flag){                for(int j=1;j<=n;++j){                    ans=min(ans,d[i][j]);                }            }        }        if(ans==INF)ans=-1;        pf("%d\n",ans);    }}



0 0
原创粉丝点击