- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我已经给出了一些数字 {a,b,c,d},我可以多次使用这些数字来得出总和“N”。我必须计算所有可能的组合,假设它是“A”,我必须返回 A%M,其中 M 是某个大质数。给我带来问题的约束是 N <= 10^18。集合 {a,b,c,d..} 的大小小于等于 100。
我正在使用动态规划来解决它,但问题是我不能使用 10^18 大小的数组,如果我不缓存预先计算的值,则会超过时间限制。
#define M 1000000007
long long solve(long long N, vector<long long>& v, vector<long long>& dp){
if(N==0){
return 1;
}
if(dp[N]!=-1){
return dp[N];
}
int n = v.size(); // maximum size of v <=100
long long ans = 0;
for(int i=0;i<n;i++){
if(N-v[i]>=0){
ans = (ans + solve(N-v[i],v,dp))%M;
}
}
dp[N] = ans;
return ans;
}
int main(){
long long n, N; // n: size of set , N: expected sum
cin>>n>>N;
vector<long long>v(n);
for(int i=0;i<n;i++){
cin>>v[i];
}
long long ans = 0;
vector<long long>dp(N+1,-1);
for(int i = 0;i<n;i++){
if(N-v[i]>=0){
ans = (ans + solve(N-v[i],v,dp))%M;
}
}
cout<<ans<<endl;
}
如何优化它以在不耗尽时间的情况下处理总和 10^18。
最佳答案
为了举例,我假设您的集合是 {1, 1, 3}
并且我们要计算第 100
项。但这种方法通常会奏效。
让 k
成为你的集合中的最大值。设 s[i]
为使 i
求和的方法数。我们的起始条件是 s[-k+1] = 0
, s[-k+2]= 0
, ..., s[-1] = 0
但 s[0] = 1
。 {a, b, c, ...}
的归纳步骤是 s[n] = s[n-a] + s[n-b] + s[n-c] + ...
.
但现在重新概念化它。考虑向量 v[n] = (s[n-k+1], s[n-k+2], ... + s[n])
。设 A[m]
是您必须乘以得到向量 v[n+m] = (s[n+m-k+1], s[n +m-k+2], ..., s[n+m])
。我会假设它存在。如果您想解决斐波那契数列的一般证明。
现在我们需要关于这些矩阵的两个事实。
第一个是 A[m1 + m2] = A[m1] * A[m2]
。要看到这一点,只需注意对于所有 n
,(A[m1] * A[m2])(v[n]) = A[m1]( A[m2]( v[ n] ) ) = A[m1]( v[n + m2] ) = v[n + m2 + m1] = A[m1 + m2]( v[n] )
。
第二个是我们可以很容易地计算A[1]
。它的上对角线全为 1,最后一行在我们集合中的任何地方都有 +1。 (或者如果该元素在我们的集合中出现两次,则为 +2,正如我在示例中确定的那样。)所以对于我们的示例,我们有:
[0 1 0] [ v[n-2] ] [ v[n-1] ]
[0 0 1] * [ v[n-1] ] = [ v[n] ]
[1 0 2] [ v[n] ] [ v[n+1] ]
初始矩阵为A[1]
。
现在假设我们要计算s[100]
。那是 v[100]
的最后一个条目。但现在我们按如下方式减半:A[100] = A[50] * A[50]
。 A[50] = A[25] * A[25]
。 A[25] = A[12] * A[13]
。 A[13] = A[1] * A[12]
。 A[12] = A[6] * A[6]
。 A[6] = A[3] * A[3]
。 A[3] = A[2] * A[1]
。最后,A[2] = A[1] * A[1]
。但是我们有 A[1]
,这在 8 次矩阵乘法后得到了 A[100]
。由于一切都呈指数增长,理论上的答案有大得离谱的整数,但这些操作很容易做 mod p
。
这可行吗?如果 n = 10**18
我们最多有大约 60 次减半,使用这种天真的方法,每一次减半都可以有另一个 +1 乘法以进行 120 次矩阵运算。如果该集合的最大元素是 100,则每次矩阵乘法(一半乘法,一半加法)大约有 200 万次,需要 2.4 亿次运算。
您还有很多工作要做。但使用这种矩阵方法,它至少是可行的。
关于algorithm - 如何计算元素的所有可能子集加起来等于给定数字的重复元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56992998/
根据小节 11.4.8 ECMAScript 5.1 标准: The production UnaryExpression : ~ UnaryExpression is evaluated as fo
我正在尝试构建一个“新评论”功能,向用户显示自上次访问以来的新评论数量。我构建了一个“ View ”表,其中包含主题 ID、用户 ID 和时间戳。每次用户访问该主题时更新时间戳或插入新行(如果不存在)
如标题所述,为什么: > !!1=="1" 等于 True 和 > !!2=="2" 等于: False 同样,为什么 > "1"==true 等于 true 而 > "2"==true 等于 fal
我在 Stack Overflow post 上看到了下图 但是,我对“p OR q”、“p AND q”的结果感到困惑,其中“p”等于“false”,“q”等于“unknown”。 在图中,“p O
一栏有效 whereJsonContains('VehicleApplications' ,['ModelName' => $model, 'YearID' => $year] )->
如果满足条件,我如何才能只获取特定记录? 我有代码为 "SELECT a.id, a.text, a.uid, a.time FROM story a INNER JOIN friends b
我正在尝试运行 MongoDB 查询并返回字段为空的记录(更具体地说,在 pyMongo 中为 None)。所以它必须等于 null。 我知道这不等于: {"firstName": {"$ne": N
我在 Java 中进行单元测试时遇到问题。 我把我的代码和错误放在这里。在互联网上我发现这是哈希码的问题。我需要重新创建它们,但我不知道为什么以及如何。 我的方法: public void setGr
如何在 Typescript 中实现 equals? 我尝试了几种方法,都没有奏效。 选项1: abstract class GTreeObject{ abstract equals(obj:
我查看了很多地方,大多数 arraylist 示例都使用“String”作为元素,但是很难找到使用对象的地方。 假设我正在制作一个图书 Collection ,并且我有一个作者对象: class Au
$a,$b,$c = 1,2,3; print "$a, $b, $c\n"; 返回 , , 1 那么 = (equals) 是否比元组构造具有更高的优先级 - 这样做? $a,$b,($c=1
在此代码片段中,a 和 i 分别具有什么值以及为什么? int i = 1; int a = i++; 是a == 1还是a == 2? 最佳答案 a==1。然后,i==2 如果你这样做的话,那就是a
我觉得我遗漏了一些明显的东西。这是一个简单的例子来说明我的问题。 我希望 current = 3 返回“之前”。 current = 4 应该返回“key-two”,current = 5 应该返回“
有人能告诉我为什么这会返回 true 吗?我想如果我投一些东西给例如Object 然后调用.equals,将使用 Object 的默认实现。 s1 == s2 应该返回 false。 请告诉我在哪个主
我需要检查加载到 UIImage 对象文件中的文件是否等于另一个图像,如果是,则执行一些操作。不幸的是,它不起作用。 emptyImage = UIImage(named: imageName) if
我想知道什么是正确的 Java 编程范式来覆盖类 C 对象的 equals(和 hashCode)方法,在以下情况下 (a) 有没有足够的信息来确定 C 的两个实例是否相等,或者 (b) 调用方法不应
>>> (()) == () True >>> (()) () 最佳答案 () 是一个 0 元组。 (foo) 产生 foo 的值。因此,(()) 产生一个 0 元组。 来自 the tutorial
考虑这段代码: var i = 0; >> undefined i += i + i++; >> 0 i >> 0 // why not 1? 由于增量 (++) 运算符,我希望 i 为 1。我认为
在我看来,TValue 似乎缺少一个强制方法; TValue.Equals(TValue)。 那么比较 2 个 TValue 的快速且合适的方法是什么,最好不使用 TValue.ToString(),
使用 SQL 时,在 WHERE 子句中使用 = 代替 LIKE 有什么好处吗? 如果没有任何特殊的运算符,LIKE 和 = 是相同的,对吧? 最佳答案 不同的运算符 LIKE 和 = 是不同的运算符
我是一名优秀的程序员,十分优秀!