原题出处:1186 -- 方程的解数http://poj.org/problem?id=1186
参考出处:
http://wenku.baidu.com/link?url=rhR0brVE9hJT-r8OGMui8VnM4paqkAL4pFv8DbTh1H5WzrUmrsvtzhA2COur1qmhm3UVMT3I78YimlGHocf9lsnRkRmaOOJjUc9p8p6jZmy
imzoer(快速求次方)
http://blog.youkuaiyun.com/imzoer/article/details/8045403
方程的解数
Description
已知一个n元高次方程:
![]() 其中:x1, x2,...,xn是未知数,k1,k2,...,kn是系数,p1,p2,...pn是指数。且方程中的所有数均为整数。 假设未知数1 <= xi <= M, i=1,,,n,求这个方程的整数解的个数。 1 <= n <= 6;1 <= M <= 150。 ![]() 方程的整数解的个数小于2 31。 ★本题中,指数Pi(i=1,2,...,n)均为正整数。 Input
第1行包含一个整数n。第2行包含一个整数M。第3行到第n+2行,每行包含两个整数,分别表示ki和pi。两个整数之间用一个空格隔开。第3行的数据对应i=1,第n+2行的数据对应i=n。
Output
仅一行,包含一个整数,表示方程的整数解的个数。
Sample Input 3 150 1 2 -1 2 1 2 Sample Output 178 Source |
问题描述:
已知n元高次方程
其中方程中所有数均为整数
指数pi(i=1,2 ... n)均为正整数,系数ki(i=1,2 ... n)均为整数(可正可负)
由1 ≤ xi ≤ M,1 ≤ M ≤ 150知,未知数xi(i=1,2 ... n)均为正整数且最大值不超过150
任务:
求方程整数解的个数
约束条件:
1 ≤ n ≤ 6,1 ≤ M ≤ 150
由此知,n元高次方程所有项的和可用int型存储
方程的整数解的个数小于231
则计算结果可用int型存储
解法:
第一想法:
计算系数ki(i=1,2 ... n)和指数pi(i=1,2 ... n)已知的情况下所有可能出现的和,求其中值为0的算式个数
于每个变量xi(i=1,2 ... n)枚举所有可能的取值:0 ... M( 1 ≤ M ≤ 150 )。当和为0时,即得到一个解,解计数变量+1
但时间复杂度为指数级,必定超时
第二想法:
减少搜索·只搜索x1 --> xn-1
计算系数ki(i=1,2 ... n)和指数pi(i=1,2 ... n)已知的情况下前n-1项和,求其中可能存在满足题意xn的算式个数
xn可取值为给定区间(0 ... M)内的整数时,即得到一个解,解计数变量+1
但时间复杂度仍为指数级
第三想法:get√
减少搜索·双向搜索 (移一半项到方程右部)
令[【x】表示不大于x的最大整数
计算系数ki(i=1,2 ... 【n/2】)和指数pi(i=1,2 ... 【n/2】)已知的情况下前【n/2】项所有可能出现的和存入一个字典left
计算系数ki(i=【n/2】+1,【n/2】+2 ... n)和指数pi(i=【n/2】+1,【n/2】+2 ... n)已知的情况下后【n/2】项所有可能出现的和存入一个字典right
字典left与字典right中某两记录的值互为相反数时,即得到一个解,解计数变量+1
字典的组织:
1.二分查找(需排序)
2.HashTable(把和值作为关键码采用除余法)
选择一个适当正整数 p,令h(k)=k%p,h(k)为关键码k的哈希地址
p选取的是比较大的素数,效果比较好
冲突处理:
令哈希表元素个数s
若h(k)已存储其他关键码,则依次探查(h(k)+i)%s(i=1,2,3 … )
到找到未存储关键码的存储单元为止
进一步优化:
将各项中的未知数xi(1 ≤ xi ≤ M,1 ≤ M ≤ 150)取各值时的结果保存到数组中,以避免重复计算
时间复杂度为O(logn)的求次方算法
----------------------------------------------------------------------------------------------------------------------------------------------------------------------