折半搜索+hash——CODEVS1735 [NOI2001]方程的解数
2017-03-28 14:58
519 查看
NOI2001的题可以搜索A掉啊
http://codevs.cn/problem/1735/
看到数据有点萎。。。因为暴搜的时间复杂度150^6
那么试试折半搜索???
我们把全部数折半(前n/2个和后n/2个)然后分别暴搜
前半部分的答案可以保存在hash表中,方便与后半部分合并
时间复杂度完美优化到150^3
然后hash的模数再好好注意一下
然后就结束了
http://codevs.cn/problem/1735/
看到数据有点萎。。。因为暴搜的时间复杂度150^6
那么试试折半搜索???
我们把全部数折半(前n/2个和后n/2个)然后分别暴搜
前半部分的答案可以保存在hash表中,方便与后半部分合并
时间复杂度完美优化到150^3
然后hash的模数再好好注意一下
然后就结束了
#include<bits/stdc++.h> using namespace std; const int MOD=5000017; int ha[5000027]={0},sum[5000027]={0},mi[151][151]; int n,m,k[1001],p[1001],ans=0; inline int hash(int p){ int w=abs(p)%MOD; while(sum[w]&&ha[w]!=p){w++;if(w==MOD)w=0;} return w; } inline void dfs(int x,int s){ if(x==n/2+1){ int p=hash(s);ha[p]=s; sum[p]++;return; } for(int i=1;i<=m;i++)dfs(x+1,s+k[x]*mi[i][p[x]]); } inline void dfss(int x,int s){ if(x==n+1){ int p=hash(s); ans+=sum[p];return; } for(int i=1;i<=m;i++)dfss(x+1,s-k[x]*mi[i][p[x]]); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){mi[i][0]=1; for(int j=1;j<=150;j++)mi[i][j]=mi[i][j-1]*i;} for(int i=1;i<=n;i++)scanf("%d%d",&k[i],&p[i]); dfs(1,0); dfss(n/2+1,0); printf("%d",ans); return 0; }
相关文章推荐
- 【codevs1735】【NOI01】方程的解数(双向搜索)
- [NOI2001]方程的解数
- COGS 304. [NOI2001] 方程的解数 meet in the middle
- codevs 1704 [NOI2001] 食物链 并查集
- 八数码问题(hash+折半搜索)
- NOI2001方程的解数 (DFS技巧:meet in the middle)(非哈希)
- [CodeVS1735]方程的解数 做题笔记
- NOI2001 方程的解数
- Wannafly模拟赛3 贝伦卡斯泰露 【折半搜索+hash,状压dp】
- poj 1186 方程的解数【折半dfs+hash】
- 【浅谈折半搜索】POJ1186[方程的解数]题解
- code vs 1735 方程的解数 (dfs+hash)
- 【meet in the middle深度优先搜索】 NOI2001方程的解数
- 【CodeVS】1229 数字游戏 开放性 搜索 Hash
- NOI 2001 第二试 方程的解数
- 【noi2001】方程的解数
- 【NOI2001】聪明的打字员 - 类似8数码的搜索题
- poj3977(折半搜索)
- geohash:用字符串实现附近地点搜索
- geohash:用字符串实现附近地点搜索