他发现的功能是FN = FN-1 + FN-2 + FN-1×FN-2
鉴于他在第0天和第1天的收入,计算他在第N天的收入(是的就这么简单)。
INPUT:
第一行输入由一个整数T组成,表示测试用例的数量。
下一个T行中的每一行分别由三个整数F0,F1和N组成。
输出:
对于每个测试用例,打印一个整数FN,因为输出可以很大,计算答案模数为109 + 7.
约束:
1≤T≤105
0≤F0,F1,N≤109
def function(x1):
if x1==2: return fnc__1+fnc__0*fnc__1+fnc__0
elif x1==1: return fnc__1
elif x1==0: return fnc__0
return function(x1-1)+function(x1-2)*function(x1-1)+function(x1-2)
for i in range(int(input())): #input() is the no of test cases
rwINput = input().split()
fnc__0 =int(rwINput[0])
fnc__1 = int(rwINput[1])
print(function(int(rwINput[2])))
答案 0 :(得分:2)
一种简单的优化方法是缓存函数的结果。 python为其lru_cache
提供了一种机制。你需要做的就是用这个来装饰你的功能:
from functools import lru_cache
@lru_cache()
def function(n, F0=1, F1=2):
if n == 0:
return F0
elif n == 1:
return F1
else:
f1 = function(n-1, F0, F1)
f2 = function(n-2, F0, F1)
return f1+f2 + f1*f2
您可以根据自己的需要调整lru_cache
。它与python垃圾收集器一起使用非常好,因为它只将WeakRefs
存储到你的对象中。
测试用例:
for i in range(7):
print('{}: {:7d}'.format(i, function(i)))
打印:
0: 1
1: 2
2: 5
3: 17
4: 107
5: 1943
6: 209951
让你的答案以整数为模(不清楚问题中的模数)你可以这样做:
MOD = 10**9 + 7 # ???
@lru_cache()
def function(n, F0=1, F1=2):
if n == 0:
return F0
elif n == 1:
return F1
else:
f1 = function(n-1, F0, F1)
f2 = function(n-2, F0, F1)
return (f1+f2 + f1*f2) % MOD
答案 1 :(得分:1)
您可以开始执行该功能,并将f1
分配给f0
,并将结果分配给f1
。迭代此n
次,所需结果位于f0
:
MOD = 10**9 + 7
for _ in range(int(input())):
f0, f1, n = (int(x) for x in input().split())
for _ in range(n):
f0, f1 = f1, (f0 + f1 + f0 * f1) % MOD
print(f0)
输入:
8
1 2 0
1 2 1
1 2 2
1 2 3
1 2 4
1 2 5
1 2 6
10 13 100
输出:
1
2
5
17
107
1943
209951
276644752
答案 2 :(得分:0)
有人给了我这个答案但它有效但我不知道怎么办?复杂性O(登录)
#include <stdio.h>
#include <stdlib.h>
#define mod 1000000007
long long int power(long long int,long long int);
void mult(long long int[2][2],long long int[2][2]);
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
int n;
int pp,p;
scanf("%d%d%d",&pp,&p,&n);
long long int A[2][2] = {{1,1},{1,0}};
n = n-1;
long long int B[2][2] = {{1,0},{0,1}};
while(n>0)
{
if(n%2==1)
mult(B,A);
n = n/2;
mult(A,A);
}
long long int result = ((power(pp+1,B[0][1])*power(p+1,B[0][0]))%mod - 1 + mod)%mod;
printf("%lld\n",result);
}
}
long long int power(long long int a,long long int b)
{
long long int result = 1;
while(b>0)
{
if(b%2==1)
result = (result*a)%mod;
a = (a*a)%mod;
b = b/2;
}
return result;
}
void mult(long long int A[2][2],long long int B[2][2])
{
long long int C[2][2];
C[0][0] = A[0][0]*B[0][0] + A[0][1]*B[1][0];
C[0][1] = A[0][0]*B[0][1] + A[0][1]*B[1][1];
C[1][0] = A[1][0]*B[0][0] + A[1][1]*B[1][0];
C[1][1] = A[1][0]*B[0][1] + A[1][1]*B[1][1];
A[0][0] = C[0][0]%(mod-1);
A[0][1] = C[0][1]%(mod-1);
A[1][0] = C[1][0]%(mod-1);
A[1][1] = C[1][1]%(mod-1);
}
答案 3 :(得分:-1)
我知道这篇文章已经过时了,但是我想指出一个重要的问题已经被忽略了:该函数很快就获得了巨大的价值,并且只需要取模。可以用模的和或积来计算总和或乘积的模。因此,获得大N值的正确答案的唯一方法是存储模数,而不是Fn!
这是我关于应如何使用动态编程的观点。动态编程只是为了缓存结果,以避免重新计算递归树的所有子分支。存储连续的Fn是所需的一切。如果该算法只需要使用一次,那么您甚至不必在此处存储整个数组:计算f0和f1,并保留最后两个计算值(带有模数),以通过简单的循环查找结果。如果算法多次运行,但结果仍未计算,则只需检索最后两个计算值(用于存储最后一个计算值索引的变量将很有用),以便从那里重新开始。