LA 7360 Run Step
阿新 • • 發佈:2018-07-15
cpp 還要 枚舉 fin tdi 題解 con printf ems
寫完這場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