Description
摩尔庄园里所有的快乐都由小摩尔们一起创造,一起分享,除了庄园入口,摩尔庄园的围墙也是由小摩尔志愿者重兵把守。
这些志愿者在执勤的时候是不能说话,但是相邻小摩尔们可以手牵手进行无声交流。为了保证执勤的秩序,规定不允许4个或更多的人联系在一起。
守卫庄园的小摩尔们每天数量不一。现在可可要回答出他们有多少种牵手方式,才能在他们的注目礼中,昂首挺胸步入摩尔庄园。
例如,总共有4个人,那么可以有以下7种方式:
1,1,1,1
1,2,1
1,1,2
2,1,1
2,2
1,3
3,1
你能不能帮助可可解决这个问题呢?
Input
共一行。一个1~10000的正整数n,表示共有n个小摩尔。
Output
共一行。输出一个正整数表示n个小摩尔牵手的方式数目。
Sample Input
4
Sample Output
7
思路
全网唯一一道该题题解系列,冷门破题(可能不久就只是第一道该题题解系列了)
谨以此题,纪念我因错误算法而浪费的3天
论手玩数据错误的悲哀(以后还是用WPS打表吧)
该题设f[i]为i个摩尔的牵手数,则:
f
[
i
]
=
f
[
i
−
1
]
+
f
[
i
−
2
]
+
f
[
i
−
3
]
,
其
中
f
[
1
]
=
1
,
f
[
2
]
=
2
,
f
[
3
]
=
4
f[i]=f[i-1]+f[i-2]+f[i-3],其中f[1]=1,f[2]=2,f[3]=4
f[i]=f[i−1]+f[i−2]+f[i−3],其中f[1]=1,f[2]=2,f[3]=4
code:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
short int a2[10001][3001],b[10001],n,e,p;//short出奇迹,int就MLE了
short int h(short int x)
{
memcpy(a2[x],a2[x-1],sizeof(a2[x]));
e=b[x-1];
for (int i=1;i<=e+3;i++)
{
p+=a2[x][i]+a2[x-2][i];
a2[x][i]=p%10;
p/=10;
}
for (int i=1;i<=e+3;i++)
{
p+=a2[x][i]+a2[x-3][i];
a2[x][i]=p%10;
p/=10;
}
e+=3;
while (e!=b[x-1]&&a2[x][e]==0) e--;
return e;
}
void print(short int x)
{
for (short int i=b[x];i>=1;i--) printf("%d",a2[x][i]);
return;
}
int main()
{
cin>>n;
a2[1][1]=1;
b[1]=1;
b[2]=1;
b[3]=1;
a2[2][1]=2;
a2[3][1]=4;//边界
for (short int i=4;i<=n;i++) b[i]=h(i);
print(n);
return 0;
}
错误(TLE且可能WA的错误算法)算法:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
string a3[40001]={"1","1"},ans="1";
int a2[40001],c[40001],b[40001],n,maxn=40001;
void mul(int b)//加减乘除应有尽有呜呜呜(一个加八聚氧还t的破题)
{
memcpy(a2,c,sizeof(a2));
memset(c,0,sizeof(c));
for (int i=1;i<=40000;i++)
{
int g=0;
c[i]=a2[i]*b;
}
for (int i=1;i<=40000;i++)
{
c[i+1]+=c[i]/10;
c[i]=c[i]%10;
}
return;
}
string prit()
{
string c1="";
int i=40000;
while (i>=1&&c[i]==0) i--;
while (i>=1)
{
long long u=c[i];
char x=u%10+'0';
c1+=x;
i--;
}
return c1;
}
void scn(string x)
{
memset(c,0,sizeof(c));
for (int i=1,j=x.size()-1;j>=0;i++,j--) c[i]=x[j]-'0';
return;
}
string h(string a1,string b1)
{
int p=0;
string c1="";
memset(a2,0,sizeof(a2));
memset(b,0,sizeof(b));
int e=(a1.size()>b1.size()?a1.size():b1.size());
for (int i=0,j=a1.size()-1;j>=0;i++,j--)
{
a2[i]=a1[j]-'0';
}
for (int i=0,j=b1.size()-1;j>=0;i++,j--) b[i]=b1[j]-'0';
for (int i=0;i<=e;i++)
{
p+=a2[i]+b[i];
char x=p%10+'0'; string x2="";x2+=x;
p/=10;
c1.insert(0,x2);
}
while (c1[0]=='0') c1.erase(0,1);
return c1;
}
bool comp(int a[],int b[])
{
int i=0;
while (a[i]==b[i]&&i<maxn) i++;
if(i==maxn) return 1;
return (a[i]>=b[i]);
}
void sub()
{
int g=0;
for(int i=maxn-1;i>0;i--)
{
if (a2[i]-b[i]-g>=0)
{
a2[i]=a2[i]-b[i]-g;
g=0;
}
else
{
a2[i]=10+a2[i]-b[i]-g;
g=1;
}
}
return;
}
void add(int n)
{
int g=0;
c[n]++;
for(int i=n;i>=1;i--)
{
c[i]=c[i]+g;
g=c[i]/10;
c[i]=c[i]%10;
}
}
string work(string str1,string str2)
{
int m=0;
memset(a2,0,sizeof(a2));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
for (int i=0;i<str1.size();i++) a2[maxn-str1.size()+i]=str1[i]-'0';
for (int i=0;i<str2.size();i++) b[maxn-str2.size()+i]=str2[i]-'0';
int j=1;
while (comp(a2,b))
{
j++;
for (int i=2;i<maxn;i++)
{
b[i-1]=b[i];
b[i]=0;
}
m=j;
}
while (j>0)
{
while (comp(a2,b))
{
add(maxn-j);
sub();
}
j--;
for (int i=maxn-1;i>=1;i--)
{
b[i]=b[i-1];
}
}
string c1="";
int i=maxn-1;
while (i>0&&c[i]=='0') i--;
while (i>0)
{
int p=c[i];
char x=p%10+'0'; string x2="";x2+=x;
p/=10;
c1.insert(0,x2);
i--;
}
while (c1[0]=='0') c1.erase(0,1);
return c1;
}
string ch(string x,int y)
{
string c1="";
int y2=y,s=0,i,j=1;
while (y2!=0)
{
y2/=10;
s++;
}
for (i=x.size()-1;j<=s;j++,i--) y2=y2*10+x[i]-'0';
if (y2<y) y2=y2*10+x[i--]-'0';
for (;i>=0;i--)
{
char xx=y2/y+'0';
c1+=xx;
y2%=y;
y2=y2*10+x[i]-'0';
}
char xx=y2/y+'0';
c1+=xx;
y2%=y;
y2=y2*10+x[i]-'0';
return c1;
}
int main()
{
cin>>n;
if (n==1)//特判
{
cout<<1;
return 0;
}
if (n==2)
{
cout<<2;
return 0;
}
if (n==3)
{
cout<<4;
return 0;
}
c[1]=1;
for (int i=2;i<n;i++) mul(i),a3[i]=prit();
string u;
int j,k;
for (int i=n-2;i>=0;i--)
{
j=(n-i)/2,k=0;//排列组合加优化
u=work(work(work(a3[i+j+k],a3[i]),a3[j]),a3[k]);
ans=h(ans,u);
scn(u);
if ((n-i)%2) j--,k++;
while (j-3>=0)
{
mul(j*(j-1)*(j-2));
u=prit();
j-=3;
u=ch(u,(k+1)*(k+2));
k+=2;
ans=h(ans,u);
}
}
cout<<ans;
return 0;
}