出题人:黄正鹏
单位:贵州工程应用技术学院
小宝喜欢在光滑的地板上摩擦或走路。假设他拥有N格体力。初始摩擦值为0,每次可以选择可以摩擦或者行走。摩擦消耗两格体力,第n次的摩擦值=第n-1次的摩擦值的2倍+2。行走消耗一格体力,第n次的摩擦值=第n-1次的摩擦值+1。求最大的摩擦值为多少?
输入格式:第一行有一个正整数K。
接下来有K行,每行有一个数N。
数据保证1≤K≤100 ,0≤N≤1 000 0。摩擦值对1 000 000 007取模。
输出k行,第i行代表第i个数据的的结果。
输入样例:2
1
5
输出样例:
1
10
思路:
法一:
找规律,n为偶则直接选两步走法,n为奇则先走一步之后全部走两步
#include
#define mod 1000000007
using namespace std;
long long dp[10010];
int main()
{
int k;
cin>>k;
while(k--){
int n;
long long m = 0;
cin>>n;
fill(dp, dp+n, 0);
if(n%2){
m++;
n--;
}
while(n){
m = (m*2+2)%mod;
n -= 2;
}
cout<<m<<endl;
}
}
法二:
动态规划,利用dp[i] = max(dp[i-1]+1, dp[i-2]*2+2)求解,不过这里需要注意题目有坑,当递推到足够大的数的时候,这时相邻的两个数据可能一个比1 000 000 007小,一个比它大,在这样取模之后再比较就会出问题。
实测n<50两种方法答案一样,验证了这种思路是对的。因此需要换一种语言:python,利用其能够表示极大范围的数据的特点。
dp = [0 for i in range(10010)]
dp[0] = 0
dp[1] = 1
for i in range(2, 10000):
dp[i] = max(dp[i-1]+1, dp[i-2]*2+2)
k = int(input())
while k != 0:
k -= 1
n = int(input())
dp[n] = dp[n]%1000000007
print(dp[n])
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)