码迷,mamicode.com
首页 > 其他好文 > 详细

LA 7360 Run Step

时间:2018-07-15 13:46:19      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:lse   枚举   class   can   scanf   ring   cpp   names   记忆   

写完这场acm模拟赛去看题解,发现自己这道题的写法跟标程不一样就发出来。标程是组合数的,但是我用记忆化搜索水过去了。
定义状态状态f[two][_two][one][_one],表示左脚还要走two次2步长,one次1步长,右脚还要走_two次2步长,_one次1步长。然后每次枚举two和one进行记忆化搜索。

#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;
LL f[51][51][51][51],ans[51];
int tot,two,_two,one,_one;
LL dfs(int a){
    if(a==tot) return 1;
    LL ans=0;
    if(~f[two][_two][one][_one]) return f[two][_two][one][_one];
    if(a%2){
        if(two){
            two--;
            ans+=dfs(a+1);
            two++;
        }
        if(one){
            one--;
            ans+=dfs(a+1);
            one++;
        }
    }else{
        if(_two){
            _two--;
            ans+=dfs(a+1);
            _two++;
        }
        if(_one){
            _one--;
            ans+=dfs(a+1);
            _one++;
        }
    }
    return f[two][_two][one][_one]=ans;
}
int main(){
    memset(f,-1,sizeof f);
    for(int n=2;n<=50;++n){
        LL answ=0;
        for(int i=1;i<=n/2;++i){
            if(n-i*2<=i){
                two=_two=i;
                one=_one=n-i*2;
                tot=two*2+one*2;
                answ+=dfs(1);
            }
        }
        ans[n]=answ;
    }
    int t,a;
    for(scanf("%d",&t);t;--t){
        scanf("%d",&a);
        printf("%d ",a);
        scanf("%d",&a);
        printf("%lld\n",ans[a/2]);
    }
    return 0;
}

跑的飞快。
后来闲着没事打了个表。

#include<cstdio>
using namespace std;
const long long ans[51]={0,0,1,4,1,9,37,16,101,425,226,1261,5342,3185,16661,70624,45397,227925,964702,654589,3192707,13483514,9533591,45499169,191695011,140024274,656975671,2761415749,2071251366,9585067029,40197719157,30823385424,141022545077,590174378453,461076613802,2089303926185,8726567622555,6928035002534,31135655962227,129811259033521,104507122669576,466323616692283,1940942711798053,1581897746416066,7014487515180361,29150498233064655,24018140388709152,105912301155194501,439511434241632076,365668377576409175,1604517292705494701};
int main(){
    int t,a;
    for(scanf("%d",&t);t;--t){
        scanf("%d",&a);
        printf("%d ",a);
        scanf("%d",&a);
        printf("%lld\n",ans[a/2]);
    }
    return 0;
}

LA 7360 Run Step

标签:lse   枚举   class   can   scanf   ring   cpp   names   记忆   

原文地址:https://www.cnblogs.com/jiaangk/p/9313251.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!