zoj-3777-Problem Arrangement(状态压缩DP)
来源:互联网 发布:美利坚淘宝之王 编辑:程序博客网 时间:2024/04/29 03:18
思路来源:http://blog.csdn.net/u013081425/article/details/23677585
http://blog.csdn.net/fulongxu/article/details/23737797
粗略分析一下:为什么这种状态压缩能减少时间运行:
方法1主要3层循环,时间复杂度有(1<<n)*n*M,对应N=12最大时考虑 (1<<12) * 12 * 500 约等于2400万次
方法2枚举遍历, 时间复杂度有 n! . 对应N=12为 12! 为479001600 约等于47900万次,可见二者此时 时间上可有20倍差距!
方法1:(状态压缩DP)
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<vector>#include<list>#include<stack>#include<queue>#include<string>#include<algorithm>using namespace std;int gys(int a,int b){ int r; if(a<b){r=a;a=b;b=r;} while(b!=0){ r =a %b; a=b; b=r; } return a;}int DP[(1<<12)+5][500+5];int P[12+1][12+1];int factorial[12+1]={1};int main(){#ifndef ONLINE_JUDGE freopen("testCase.txt","r",stdin);#endif int T,N,M; for(int i=1;i<=12;i++) factorial[i]=factorial[i-1]*i; //cin>>T; scanf("%d",&T); while(T--){ memset(DP,0,sizeof(DP)); //cin>>N>>M; scanf("%d %d",&N,&M); for(int i=0;i<N;i++) for(int j=0;j<N;j++) //cin>>P[i][j]; scanf("%d",&P[i][j]); DP[0][0] = 1; for(int i=0;i<((1<<N)-1);i++){ int cnt=0; for(int j=0;j<N;j++){ if(i&(1<<j)) cnt++; } for(int j=0;j<N;j++){ if((i&(1<<j)) == 0){ for(int k=0;k<=M;k++){ int y= (k+ P[cnt][j]) <= M?(k+P[cnt][j]):M; DP[i+(1<<j)][y] += DP[i][k]; } } } } if(DP[(1<<N)-1][M]==0) printf("No solution\n"); else{ int a= DP[(1<<N)-1][M]; int b= factorial[N]; int divid = gys(DP[(1<<N)-1][M],factorial[N]); a /= divid; b /= divid; printf("%d/%d\n",b,a); } } return 0;}
方法2:(枚举遍历,通不过OJ测试)
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<vector>#include<list>#include<stack>#include<queue>#include<string>#include<algorithm>using namespace std;int P[12*12]; //P[12][12]int T;int N,M;void swap(int *a ,int *b){int m ;m = *a;*a = *b;*b = m;} int n= 0;int accum = 0; // >M 累加void perm(int list[],int k, int m ){int i; int index =0; int total = 0;if(k > m){for(i = 0 ; i <= m ; i++){//cout<<"r"<<list[i]; index = list[i]; total += P[i*N+index]; } if(total >=M) accum++;//cout<<"/n";n++;}else{for(i = k ; i <=m;i++){swap(&list[k],&list[i]);perm(list,k+1,m);swap(&list[k],&list[i]);}}}int gys(int a,int b){ int r; if(a<b){r=a;a=b;b=r;} while(b!=0){ r =a %b; a=b; b=r; } return a;}int pos[12];int main(){#ifndef ONLINE_JUDGE freopen("testCase.txt","r",stdin);#endif //cin>>T; scanf("%d",&T); while(T--){ n = 0; accum = 0; //cin>>N>>M; scanf("%d %d",&N,&M); for(int i=0;i<N*N;i++){ scanf("%d",&P[i]); } for(int i =0;i<N;i++) pos[i] = i; perm(pos,0,N-1); //cout<< accum<<' '<< n<<endl; if(accum ==0) printf("No solution\n"); else{ int divid = gys(accum,n); accum /= divid; n /= divid; printf("%d/%d\n",n,accum); } } return 0;}
0 0
- ZOJ-3777 Problem Arrangement(dp状态压缩)
- zoj-3777-Problem Arrangement(状态压缩DP)
- ZOJ 题目3777 Problem Arrangement(状态压缩DP)
- ZOJ - 3777 Problem Arrangement(状态压缩dp)
- ZOJ 3777 Problem Arrangement (状态压缩 + 概率)
- ZOJ 3777 11th省赛 B Problem Arrangement【状态压缩DP】
- ZOJ 3777 11th省赛 B Problem Arrangement【状态压缩DP】
- zoj 3777 Problem Arrangement (好状压dp)
- ZOJ 3777 Problem Arrangement(DP)
- ZOJ 3777 - Problem Arrangement(状压DP)
- ZOJ 3777 Problem Arrangement(壮压dp)
- ZOJ 3777 Problem Arrangement (状压DP)
- zoj 3777 Problem Arrangement(状压dp)
- 数位DP(ZOJ 3777,Problem Arrangement)
- zoj3777 Problem Arrangement(状态压缩dp)
- ★ZOJ 3777 Problem Arrangement 详解(壮压DP)
- ZOJ 3777 Problem Arrangement 状压dp
- 【状压DP】 ZOJ 3777 Problem Arrangement
- 原因为什么它不值得做你自己的网站
- C语言详解 - 枚举类型
- 印度花岗岩砖 - 以帮助您通过自然生活
- HDU-4930 Fighting the Landlords 多校训练赛斗地主
- 印尼语翻译和爪哇翻译一次争斗为自定义
- zoj-3777-Problem Arrangement(状态压缩DP)
- iOS UI_APPEARANCE_SELECTOR、appearence 和UIButton加图片并调整图片和字体的位置
- 程序设计模式-观察者模式
- 医疗保健数据分析处于快速转型
- 超经典智力面试题
- HDU 1551 Cable master【二分答案】
- Halcon一些功能算子
- adb logcat 查看日志
- 温故知新——有了malloc/free为什么还要new/delete