我如何使用动态编程来优化此代码

时间:2017-01-20 09:38:19

标签: python python-3.x recursion optimization dynamic-programming

Daulat Ram是一位富裕的商人。在非货币化之后,IT突袭行动在他的所有资金被扣押的住所举行。他非常渴望获得退款,他开始投资某些企业并从中获利。在第一天,他的收入是卢比。 X,然后是卢比。 Y在第二天。 Daulat Ram观察了他的成长,并想在第N天计算他的收入。

他发现的功能是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])))

4 个答案:

答案 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,并保留最后两个计算值(带有模数),以通过简单的循环查找结果。如果算法多次运行,但结果仍未计算,则只需检索最后两个计算值(用于存储最后一个计算值索引的变量将很有用),以便从那里重新开始。