UVa 10944 状态压缩DP
2014-06-10 22:42
274 查看
第一道状态压缩DP题,感觉要好好学习这种思维方式;
首先设L的位置为:pointx[0],pointy[0];其他节点的位置为:pointx[i],pointy[i];
然后求出各个节点之间的距离dis[i][j]=max{| pointx[i]-pointx[j] |,| pointy[i]-pointy[j] |};
我们用一个n位2进制数(bn-1,...,b0)表示坚果收集情况的组合状态;
其中bi=0表示第i+1个坚果没有收集,bi-1表示第i+1个坚果收集了。
设坚果目前被收集的状态为j,其中最后被收集的坚果为i,最小步数为f[i][j].
显然初始化的时候:f[i][2的i-1次幂]=dis[0][i];
状态i:按照递增顺利枚举状态值
阶段j:枚举状态i中最后被收集的坚果j (i<=j<=n,i&2的j-1次幂!=0)
决策k:枚举状态i外的坚果k(1<=k<=n,i&2的k-1次幂==0),
f[k][i+2的k-1次幂]=min( f[k][i+2的k-1次幂] , f[j][i]+dis[j][k] );
所以最后的结果为:
ans=min(f[i][2的n-1次幂]+dis[0][i]) (1<=i<=n);
下面是代码,没有给注释,我的任务就是说一下思路,思路懂了,其他的都是小事。。。
首先设L的位置为:pointx[0],pointy[0];其他节点的位置为:pointx[i],pointy[i];
然后求出各个节点之间的距离dis[i][j]=max{| pointx[i]-pointx[j] |,| pointy[i]-pointy[j] |};
我们用一个n位2进制数(bn-1,...,b0)表示坚果收集情况的组合状态;
其中bi=0表示第i+1个坚果没有收集,bi-1表示第i+1个坚果收集了。
设坚果目前被收集的状态为j,其中最后被收集的坚果为i,最小步数为f[i][j].
显然初始化的时候:f[i][2的i-1次幂]=dis[0][i];
状态i:按照递增顺利枚举状态值
阶段j:枚举状态i中最后被收集的坚果j (i<=j<=n,i&2的j-1次幂!=0)
决策k:枚举状态i外的坚果k(1<=k<=n,i&2的k-1次幂==0),
f[k][i+2的k-1次幂]=min( f[k][i+2的k-1次幂] , f[j][i]+dis[j][k] );
所以最后的结果为:
ans=min(f[i][2的n-1次幂]+dis[0][i]) (1<=i<=n);
下面是代码,没有给注释,我的任务就是说一下思路,思路懂了,其他的都是小事。。。
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #define INF 1<<22 using namespace std; int x,y,num,ans,MAX; char ch[22][22]; int dis[22][22]; int pointx[22],pointy[22]; int f[22][INF]; int Abs(int a) { if(a<0) return -a; else return a; } void init() { int i,j; MAX=(1<<num)-1; ans=INF; for(i=0;i<=num;i++) { for(j=0;j<=num;j++) { dis[i][j]=max(Abs(pointx[i]-pointx[j]),Abs(pointy[i]-pointy[j])); } } for(i=1;i<=MAX;i++) { for(j=1;j<=num;j++) f[j][i]=INF; } for(i=1;i<=num;i++) { f[i][1<<(i-1)]=dis[0][i]; } } void dp() { int i,j,k; for(i=1;i<MAX;i++) { for(j=1;j<=num;j++) { if(i&(1<<(j-1))) { for(k=1;k<=num;k++) { if((i&(1<<(k-1)))==0) { f[k][i+(1<<(k-1))]=min(f[k][i+(1<<(k-1))],f[j][i]+dis[j][k]); } } } } } for(i=1;i<=num;i++) { ans=min(ans,f[i][MAX]+dis[0][i]); } } int main() { int i,j; while(scanf("%d%d",&x,&y)!=EOF) { num=0; for(i=1;i<=x;i++) { scanf("%s",ch[i]); for(j=0;j<y;j++) { if(ch[i][j]=='L') { pointx[0]=i; pointy[0]=j+1; } else if(ch[i][j]=='#') { pointx[++num]=i; pointy[num]=j+1; } } } if(num==0) { printf("0\n"); continue; } init(); dp(); printf("%d\n",ans); } return 0; }
相关文章推荐
- UVA - 10944 Nuts for nuts 状态压缩DP
- UVA 10944 Nuts for nuts.. (状态压缩dp)
- UVA - 11795 Mega Man's Mission 状态压缩DP
- Uva 10817 Headmaster's Headache (DP+ 状态压缩)
- uva 11795 Mega Man's Mission(动态规划-状态压缩DP)
- uva 1252(状态压缩dp)
- 状态压缩 之 UVA 10944 - Nuts for nuts..
- uva 10651 Pebble Solitaire(dp,状态压缩,记忆化搜索)
- UVA 11795 Mega Man's Mission(状态压缩DP)
- UVa 10651 Pebble Solitaire(状态压缩DP)
- UVa 10651 Pebble Solitaire(状态压缩DP)
- UVA 1252 Twenty Questions 状态压缩dp 记忆化搜索
- uva 10817 - Headmaster's Headache ( 状态压缩dp)
- UVA 11825 Hackers' Crackdown DP+状态压缩 -
- UVA 10817 Headmaster's Headache(dp 状态压缩 01背包)
- UVA 11825 Hackers' Crackdown(状态压缩DP)
- UVa 1252 - Twenty Questions(记忆化搜索,状态压缩dp)
- UVA 11795 Mega Man's Mission(状态压缩DP)
- uva 11795 Mega Man's Mission(动态规划-状态压缩DP)
- 状态压缩 之 UVA 10944 - Nuts for nuts..