1006 - Hex-a-bonacci
Time Limit: 0.5 second(s) | Memory Limit: 32 MB |
Given a code (not optimized), and necessary inputs, you have to find the output of the code for the inputs. The code is as follows:
int a, b, c, d, e, f;
int fn( int n ) {
if( n == 0 ) return a;
if( n == 1 ) return b;
if( n == 2 ) return c;
if( n == 3 ) return d;
if( n == 4 ) return e;
if( n == 5 ) return f;
return( fn(n-1) + fn(n-2) + fn(n-3) + fn(n-4) + fn(n-5) + fn(n-6) );
}
int main() {
int n, caseno = 0, cases;
scanf("%d", &cases);
while( cases-- ) {
scanf("%d %d %d %d %d %d %d", &a, &b, &c, &d, &e, &f, &n);
printf("Case %d: %d\n", ++caseno, fn(n) % 10000007);
}
return 0;
}
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case contains seven integers, a, b, c, d, e, f and n. All integers will be non-negative and 0 ≤ n ≤ 10000 and the each of the others will be fit into a 32-bit integer.
Output
For each case, print the output of the given code. The given code may have integer overflow problem in the compiler, so be careful.
Sample Input | Output for Sample Input |
5 0 1 2 3 4 5 20 3 2 1 5 0 1 9 4 12 9 4 5 6 15 9 8 7 6 5 4 3 3 4 3 2 54 5 4 | Case 1: 216339 Case 2: 79 Case 3: 16636 Case 4: 6 Case 5: 54 |
题意:将上述程序优化;
思路:主要就是优化时间复杂度,将递推式化简一下,上面的式子运行最大时间大约10000*10000左右,优化方法 就是用空间换时间,递归换一种方式就是DP思想,两者唯一不同的就是DP的中间状态保存起来了,而递归的中间状态没有被保存起来,导致下一次的查询还要计算中间值,计算了多次中间值,因此只要将中间的状态保存起来,下一次递归是就不用再计算中间值了,所以对上面的程序开一个数组保存中间结果就行了;
失误:比赛时没有想到递归转DP,把公式化简了一下(好麻烦,只是没有耐心推导,推到10项时发现了规律),其实完全是不必要的化简,比赛后再过来看这道题时才发现递归转DP,保存状态优化时间; 另外:数组大小看错,开小了,心里着急一交就错了,以后提交之前先检查一下数组大小,输出输入,数据是否溢出等格式问题,不能在形式上犯错误。
AC代码:
比赛是写的:
#include<cstdio>
typedef long long LL;
const int mod=10000007;
LL a[111111];
int main()
{
LL T,i,N,Kase=0;
scanf("%lld",&T);
while(T--)
{
scanf("%lld %lld %lld %lld %lld %lld %lld",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5],&N);
a[6]=a[0]+a[1]+a[2]+a[3]+a[4]+a[5];
for(i=7;i<=N;++i)
{
a[i]=(2*a[i-1]%mod-a[i-7]);
a[i]=(a[i]%mod+mod)%mod;
}
printf("Case %lld: %lld\n",++Kase,a[N]%mod);
}
return 0;
}
比赛后写的(如果比赛时想到,肯定几分钟解决)
#include<cstdio>
typedef long long LL;
const int mod=10000007;
LL a[111111];
int main()
{
LL T,i,N,Kase=0;
scanf("%lld",&T);
while(T--)
{
scanf("%lld %lld %lld %lld %lld %lld %lld",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5],&N);
a[6]=a[0]+a[1]+a[2]+a[3]+a[4]+a[5];
for(i=7;i<=N;++i)
{
a[i]=a[i-1]+a[i-2]+a[i-3]+a[i-4]+a[i-5]+a[i-6];
a[i]=(a[i]%mod+mod)%mod;
}
printf("Case %lld: %lld\n",++Kase,a[N]%mod);
}
return 0;
}