hdu 5459(递推+步步取模)

转自:https://www.cnblogs.com/dominatingdashuzhilin/p/4822768.html

题意:字符串s[1]=”c”,s[2]=”ff”,s[i]=s[i-2]+s[i-1] (i>=3);
对于每个n,求s[n]中所有的任意两个字符c的距离之和;

思路:用dp[i]表示s[i]的结果,dist[i]表示s[i]中所有c到s[i]末尾的距离之和,len[i]表示s[i]的长度,cnt[i]表示s[i]中c的数量;

dp[i]=dp[i-1]+dp[i-2]+cnt[i-1]dist[i-2]+cnt[i-2]((len[i-1]*cnt[i-1])-dist[i-1]);
即两边独立的距离与两边相互关联的距离和;

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define mod 530600414
int t,n,m;
long long dp[500010];
long long cnt[500010],len[500010],dist[500010];
void init(){
    int i,j,k;
    cnt[1]=1,cnt[2]=0;
    len[1]=1,len[2]=2;
    dist[1]=0,dist[2]=0,dist[3]=dist[4]=2;
    dp[1]=dp[2]=dp[3]=dp[4]=0,dp[5]=5;
    for(i=3;i<=300000;i++){
        cnt[i]=(cnt[i-1]%mod+cnt[i-2]%mod)%mod;
        len[i]=(len[i-1]%mod+len[i-2]%mod)%mod;
    }
    for(i=5;i<=300000;i++){
        dist[i]=(dist[i-1]%mod+dist[i-2]%mod+(cnt[i-2]%mod*len[i-1]%mod)%mod)%mod;
    }
    for(i=6;i<=300000;i++){
        dp[i]=(dp[i-1]%mod+dp[i-2]%mod+(cnt[i-1]%mod*dist[i-2]%mod)%mod+(cnt[i-2]%mod*(len[i-1]%mod*cnt[i-1]%mod-dist[i-1]%mod)%mod)%mod)%mod;
    }
}
int main(){
  int i,j,k;
  init();
  scanf("%d",&t);
  for(k=1;k<=t;k++){
    scanf("%d",&n);
    printf("Case #%d: ",k);
    printf("%I64d\n",dp[n]);
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值