专栏文章
题解:UVA10359 Tiling
UVA10359题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mipsyuca
- 此快照首次捕获于
- 2025/12/03 17:26 3 个月前
- 此快照最后确认于
- 2025/12/03 17:26 3 个月前
UVA10359 Tiling 题解
易发现可用 dp 求解,设 为拼出长为 的图形的方案数。
题目描述了要拼成一个 的图案,有以下 种方案:
-
在一个 的矩阵上增加一个 的图形。
-
在一个 的矩阵上增加一个 的图形。
-
在一个 的矩阵上增加一个 的图形。
所以易推出 。
由于每次至少乘 所以需要用高精度。
在乘 的时候可以用 FFT 解决。
Code:
CPP//f[i]=f[i-1]+2*f[i-2]
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int N=1<<22;
const double Pi=acos(-1.0);
int aa[1000000],bb[1000000],anss[1000000];
string add(string s1,string s2){
memset(anss,0,sizeof(anss));
memset(aa,0,sizeof(aa));
memset(bb,0,sizeof(bb));
for(int i=0;i<s1.size();i++) aa[i+1]=s1[i]-'0';
for(int i=0;i<s2.size();i++) bb[i+1]=s2[i]-'0';
reverse(aa+1,aa+s1.size()+1);
reverse(bb+1,bb+s2.size()+1);
int len=max(s1.size(),s2.size());
for(int i=1;i<=len;i++){
anss[i]+=aa[i]+bb[i];
anss[i+1]+=anss[i]/10;
anss[i]%=10;
}
bool flag=0;
if(anss[len+1]!=0) flag=1;
string res="";
for(int i=len+flag;i>=1;i--) res+=char(anss[i]+'0');
return res;
}
struct complex{
double x,y;
complex (double xx=0,double yy=0){x=xx,y=yy;}
}a[N],b[N];
complex operator + (complex a,complex b){return complex(a.x+b.x,a.y+b.y);}
complex operator - (complex a,complex b){return complex(a.x-b.x,a.y-b.y);}
complex operator * (complex a,complex b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
void FFT(int limit,complex *a,int type){
if(limit == 1) return;
complex a1[limit>>1],a2[limit>>1];
for(int i=0;i<limit;i+=2)
a1[i>>1]=a[i],a2[i>>1]=a[i+1];
FFT(limit>>1,a1,type);
FFT(limit>>1,a2,type);
complex Wn=complex(cos(2.0*Pi/limit) , type*sin(2.0*Pi/limit)),w=complex(1,0);
for(int i=0;i<(limit>>1);i++,w=w*Wn)
a[i]=a1[i]+w*a2[i],
a[i+(limit>>1)]=a1[i]-w*a2[i];
}
int n,m,ans[N];
string mul(string s1,string s2){
memset(ans,0,sizeof ans);
n=s1.size(),m=s2.size();
reverse(s1.begin(),s1.end());
reverse(s2.begin(),s2.end());
for(int i=0;i<n;i++) a[i].x=s1[i]-'0';
for(int i=0;i<m;i++) b[i].x=s2[i]-'0';
int limit=1;while(limit<=n+m-2) limit<<=1;
FFT(limit,a,1);
FFT(limit,b,1);
for(int i=0;i<=limit;i++)
a[i]=a[i]*b[i];
FFT(limit,a,-1);
for(int i=0;i<=n+m-1;i++)
ans[i]=(int)(a[i].x/limit+0.5);
for(int i=0;i<n+m-1;i++){
ans[i+1]+=ans[i]/10;
ans[i]%=10;
}
int flag=1;
string res="";
for(int i=n+m-1;i>=0;i--){
if(flag && ans[i]==0) continue;
res+=char(ans[i]+'0');
flag=0;
}
return res;
}
string dp[255];
int main(){
string sss="2";
for(int i=0;i<=250;i++) dp[i]="0";
dp[0]="1",dp[1]="1",dp[2]="3";
for(int i=3;i<=250;i++){
string tmp=add(dp[i-2],dp[i-2]);
dp[i]=add(dp[i-1],tmp);
}
int q;
while(cin>>q){
cout<<dp[q]<<endl;
}
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...