poj 1186
2015-08-08 22:28
239 查看
似乎是NOI 2001的题目,感觉很有意思。。。
Meet in the Middle (中途相遇法)
看起来O(MN)O(M^N)不可做,方程移项有真相:k1∗xp11+k2∗xp22+k3∗xp33=−(k4∗xp44+k5∗xp55+k6∗xp66)k_1*x_1^{p_1}+k_2*x_2^{p_2}+k_3*x_3^{p_3}=-(k_4*x_4^{p_4}+k_5*x_5^{p_5}+k_6*x_6^{p_6})
分别计算 :
k1∗xp11+k2∗xp22+k3∗xp33=Wk_1*x_1^{p_1}+k_2*x_2^{p_2}+k_3*x_3^{p_3} = W 的解数fL(W)f_L(W)
k4∗xp44+k5∗xp55+k6∗xp66=Wk_4*x_4^{p_4}+k_5*x_5^{p_5}+k_6*x_6^{p_6} = W 的解数fR(W)f_R(W)
那么 ans=∑fL(x)∗fR(−x)ans = \sum f_L(x)*f_R(-x)
时间复杂度:O(MN/2)O(M^{N/2})
另外注意使用 std::unique 函数之后的数组中每个值出现的次数与原数组不相同。。。
Meet in the Middle (中途相遇法)
看起来O(MN)O(M^N)不可做,方程移项有真相:k1∗xp11+k2∗xp22+k3∗xp33=−(k4∗xp44+k5∗xp55+k6∗xp66)k_1*x_1^{p_1}+k_2*x_2^{p_2}+k_3*x_3^{p_3}=-(k_4*x_4^{p_4}+k_5*x_5^{p_5}+k_6*x_6^{p_6})
分别计算 :
k1∗xp11+k2∗xp22+k3∗xp33=Wk_1*x_1^{p_1}+k_2*x_2^{p_2}+k_3*x_3^{p_3} = W 的解数fL(W)f_L(W)
k4∗xp44+k5∗xp55+k6∗xp66=Wk_4*x_4^{p_4}+k_5*x_5^{p_5}+k_6*x_6^{p_6} = W 的解数fR(W)f_R(W)
那么 ans=∑fL(x)∗fR(−x)ans = \sum f_L(x)*f_R(-x)
时间复杂度:O(MN/2)O(M^{N/2})
另外注意使用 std::unique 函数之后的数组中每个值出现的次数与原数组不相同。。。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <vector> #include <utility> #include <stack> #include <queue> #include <iostream> #include <algorithm> template<class Num>void read(Num &x) { char c; int flag = 1; while((c = getchar()) < '0' || c > '9') if(c == '-') flag *= -1; x = c - '0'; while((c = getchar()) >= '0' && c <= '9') x = (x<<3) + (x<<1) + (c-'0'); x *= flag; return; } template<class Num>void write(Num x) { if(x < 0) putchar('-'), x = -x; static char s[20];int sl = 0; while(x) s[sl++] = x%10 + '0',x /= 10; if(!sl) {putchar('0');return;} while(sl) putchar(s[--sl]); } const int maxn = 10, maxm = 155, size = maxm*maxm*maxm; int n, m, k[maxn], p[maxn]; int val[size], len, vlen, cnt[size]; long long ans = 0; void count(int rem,int v) { if(rem == 0) { val[++len] = v; return; } for(int i = 1; i <= m; i++) { int cal = k[rem]; for(int j = 1; j <= p[rem]; j++) cal *= i; count(rem - 1, v + cal); } } #define find_in_val(x) std::lower_bound(val + 1, val + vlen + 1, x) - val void prework() { static int tmp[size]; for(int i = 1; i <= len; i++) tmp[i] = val[i]; std::sort(val + 1, val + len + 1); vlen = std::unique(val + 1, val + len + 1) - (val + 1); for(int i = 1; i <= len; i++) cnt[find_in_val(tmp[i])] ++; } void dfs(int pos,int v) { if(pos > n) { int t = find_in_val(-v); if(val[t] == -v) ans += cnt[t]; return; } for(int i = 1; i <= m; i++) { int cal = k[pos]; for(int j = 1; j <= p[pos]; j++) cal *= i; dfs(pos + 1, v + cal); } } int main() { #ifndef ONLINE_JUDGE freopen("1186.in","r",stdin); freopen("1186.out","w",stdout); #endif read(n), read(m); for(int i = 1; i <= n; i++) read(k[i]), read(p[i]); count(n>>1, 0); prework(); dfs((n>>1) + 1, 0); write(ans); #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }
相关文章推荐
- poj 1186 分类: poj 2015-08-08 22:28 4人阅读 评论(0) 收藏
- C++对象模型--总结
- 做自媒体就要会讲故事
- ROS学习--(十九)使用Gazebo模拟器
- void PrintString(int Level , WCHAR *pszFormat , ...)
- ReactNavtive框架教程(6)(完)
- 6、预处理、const、sizeof
- Mac配置Python开发环境(Eclipse +Pydev+Python)
- 第八章 高效算法设计
- java关于==与equals的讨论
- springMVC
- muduo::Acceptor、TcpServer分析
- STL之vector简单实现
- 等待时动画效果的实现
- Lucene.Net+盘古分词->开发自己的搜索引擎
- Jquery实现图片轮播功能
- 常见的HTTP状态码(HTTP Status Code)说明
- 五分钟上手Git
- python easy_install django 安装
- 70.Climbing Stairs