您的位置:首页 > 其它

hdu3001 三进制 状态压缩dp

2017-04-20 22:54 225 查看
转自:

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:16

const 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 printf
const int INF=1e9;
const int N=15;
const int M=60000;
const int inf=0x3f3f3f3f;

int n,m;
//2017年5月6日08:42:30
int g

;
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);
}
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: