HDU 5459 递推好题

题意: 给定一个斐波那契字符串 Si=Si-1+Si-2
求第i项中 两两c的坐标的距离之和

思路:s[i]=s[i-1]+s[i-2],第i个字符串中的c字符可以分为两部分,来自第i-2个字符串(姑且叫做a)的和第i-1个字符串(姑且叫做b)。既然如此我们对于答案,也可以分几部分求出,a中的c坐标差的和,b中的c坐标差的和,以及两个c,一个来自a一个来自b的所有情况的坐标差的和。

前面两个很容易得到,就是ans[i-2]和ans[i-1]的值。对于后面的情况即是所有的bj-ai相加之和(ai表示a中第i个c的坐标,bi表示b中第j个c的坐标).
那么如果我们从a中选出的c为第i个的情况有多少种呢?不难看出即为b中c的个数
这里我们假定a中某个c的贡献只考虑b中c减a中c,那么a中某个c的贡献就是b中c的坐标和-a中那个c的坐标和。

所以对于这个式子我们可以改写成所有情况中所有从a选取的c的坐标和,减去从b选取c的坐标和(这里的坐标可以认作他们的位置,但是对于b来说,它的坐标为为它在b中的位置加上a的长度)。所以式子可以化简为:(sum[i-1]+num[i-1]*len[i-2])*num[i-2]-sum[i-2]*num[i-1]。

#include<iostream>
#include<algorithm>
#include<string.h>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int mod=530600414;
const int maxn=222222;
ll len[maxn],num[maxn],sum[maxn],ans[maxn];
int main()
{
	len[1]=1;
	len[2]=2;
	num[1]=1;num[2]=0;
	ans[5]=5;ans[6]=16;
	sum[5]=7;sum[6]=20;
	for(int i=3;i<=201314;i++)
		len[i]=(len[i-1]+len[i-2])%mod,num[i]=(num[i-1]+num[i-2])%mod;
	for(int i=7;i<=201314;i++)
		sum[i]=(sum[i-1]+sum[i-2]+(num[i-1]*len[i-2])%mod)%mod;
	for(int i=7;i<=201314;i++)
		ans[i]=(ans[i-1]+ans[i-2]+((sum[i-1]+(num[i-1]*len[i-2])%mod)%mod*num[i-2])%mod-(num[i-1]*sum[i-2])%mod)%mod;
	int t;
	cin>>t;
	int ok=1;
	while(t--)
	{
		int n;
		cin>>n;
		printf("Case #%d: ",ok++);
		cout<<(ans[n]+mod)%mod<<endl;
	}
	return 0;
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值