2017 计蒜之道 复赛 腾讯消消乐
2017-06-11 21:05
579 查看
官网题解 用f(mask,step) 表示考虑当前mask 集合内的数用 step 步删除完的方案数,每次转移则可以简单地用 O(n^2) 来进行枚举删掉的一段区间进行转移。 就是 记忆化搜索/dp
递归会超时。还是能for循环就for循环。
判断dp[S][step]+=dp[tmpS][step-1]能否转移的小小优化。
可以枚举所有i~j预处理所有状态能不能消除,转移的时候O(1)判断(在代码中表现为can[tmpS]是1还是0)。
也可以把所有能转移的状态加到链表里。
#include <iostream> #include<stdio.h> #include<algorithm> #include<string.h> #include<set> #include<cmath> #include<vector> #include<queue> using namespace std; typedef long long ll; const int maxn=100000; const int MAXN=1000; int n,m; const ll inf=0xfffffffffffffff; const ll mod= 1000000007; int a[100]; int gcd(int a,int b){ return b==0?a:gcd(b,a%b); } ll dp[(1<<19)][20]; bool can[(1<<20)]; ll S; void dfs(int s,int step){ if(dp[s][step]!=-1){ return ; } if(s==0||step==0){ if(s==0&&step==0){ dp[s][step]=1; }else{ dp[s][step]=0; } return ; } ll res=0; for(int i=0;i<n;i++){ if(!((s>>i)&1 ) ){ continue; } for(int j=i;j<n;j++){ if( !((s>>j)&1) ){ continue; } int canS=s &(( (1<<(j+1) )-1) -( (1<<(i))-1)); if(can[canS]){ int tmpS=s&( S ^ (( (1<<(j+1) )-1) -( (1<<(i))-1))); dfs(tmpS,step-1); res+=dp[tmpS][step-1]; res%=mod; } } } dp[s][step]=res; } void init(){ dp[0][0]=1; for(int s=1;s<=S;s++){ for(int p=1;p<=n;p++){ ll res=0; for(int i=0;i<n;i++){ if(!((s>>i)&1 ) ){ continue; } for(int j=i;j<n;j++){ if( !((s>>j)&1) ){ continue; } int canS=s &(( (1<<(j+1) )-1) -( (1<<(i))-1)); if(can[canS]){ int tmpS=s&( S ^ (( (1<<(j+1) )-1) -( (1<<(i))-1))); res+=dp[tmpS][p-1]; res%=mod; } } } dp[s][p]=res; } } } int main() { if(fopen("H:\\acm.txt","r")){ freopen("H:\\acm.txt","r",stdin); } while(scanf("%d%d",&n,&m)!=EOF){ for(int i=0;i<n;i++){ scanf("%d",&a[i]); } S=(1<<n)-1; for(int s=0;s<=S;s++){ int gc,tmp=0; for(int k=0;k<n;k++){ if((s>>k)&1){ if(tmp++==0){ gc=a[k]; } gc=gcd(gc,a[k]); if(gc<m){ tmp=0; break; } } } if(tmp>0){can[s]=1;} else can[s]=0; } // for(int i=0;i<=S;i++){ // for(int j=0;j<=n;j++){ // dp[i][j]=-1; // } // } // for(int i=1;i<=n;i++){ // dfs(S,i); // } init(); ll res=0; for(ll i=1;i<=n;i++){ res+= (dp[S][i]*i)%mod; res%=mod; } cout<<res<<endl; } return 0; }
相关文章推荐
- 计蒜之道-2017复赛-腾讯消消乐(状压DP)
- 计蒜之道-2017复赛-腾讯消消乐(状压DP)
- (状压dp)2017 计蒜之道 复赛 F. 腾讯消消乐
- 计蒜客-2017 计蒜之道 复赛-F-腾讯消消乐
- 2017 计蒜之道 复赛 腾讯消消乐【状压dp】
- 计蒜之道 2017 程序设计大赛 - 计蒜客 复赛 F 腾讯消消乐 状态压缩dp、枚举+剪枝
- 计蒜客 2017 复赛 腾讯消消乐 (状压dp)
- 计蒜之道复赛 腾讯消消乐
- 计蒜客 2017 复赛 腾讯消消乐 状压dp
- 腾讯2017暑期实习生编程题——算法基础-字符移位
- 腾讯2017暑期实习生编程题
- 腾讯2017秋招笔试编程题(三)---素数对
- [笔试编程题] 腾讯2017暑期实习生编程题-java
- 腾讯2017秋招笔试编程题(四)----geohash编码
- 2017百度之星复赛:1006. Valley Numer(数位DP)
- [2017百度之星程序设计大赛 - 复赛]A - hdu6144 B - hdu6145
- 腾讯2017暑期实习生编程题-B-算法基础-字符移位
- 腾讯技术工程 | 厉害了!腾讯AI Lab首次参加知识图谱顶级赛事KBP 2017,就夺得世界冠军
- 2017 计蒜客复赛 D.百度地图导航
- [数位DP Lucas定理] 2017 计蒜之道 复赛 E. 商汤智能机器人