题意:求最长上升序列长度和方案数。
思路:经典DP,不需什么别的东西,加一个数组储蓄程序数即可,原题300000可能N2会有问题,但问题不大。
见代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int n,type,q,a[100001],flag,b[100001],c[100001],sum; int main() { freopen("hamon.in","r",stdin); freopen("hamon.out","w",stdout); cin>>n>>type; for(int i=1;i<=n;i++) { c[i]=b[i]=1; cin>>a[i]; q=0; for(int j=1;j<i;j++) { if(a[j]<a[i]) { if(q!=0) if(b[j]==b[i]-1) c[i]+=c[j]; if(b[j]>=b[i]) { if(b[j]>b[i]) { c[i]=c[j]; b[i]=b[j]; } if(b[j]==b[i]) { c[i]=c[j]; b[i]=b[j]+1; } q=1; } } } } for(int i=1;i<=n;i++) { if(b[i]>b[flag]) { flag=i; } } cout<<b[flag]<<endl; if(type==1) { for(int i=1;i<=n;i++) if(b[i]==b[flag]) sum+=c[i]; cout<<sum%123456789; } return 0; }
下面是悔恨时间。
不开long long毁一生!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
因为方案数很大,题中说要%123456789,一不小心没开long long
好气啊!!!
见代码*2:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int n,type,q,a[100001],flag,b[100001]; long long c[100001],sum; int main() { freopen("hamon.in","r",stdin); freopen("hamon.out","w",stdout); cin>>n>>type; for(int i=1;i<=n;i++) { c[i]=b[i]=1; cin>>a[i]; q=0; for(int j=1;j<i;j++) { if(a[j]<a[i]) { if(q!=0) if(b[j]==b[i]-1) c[i]+=c[j]; if(b[j]>=b[i]) { if(b[j]>b[i]) { c[i]=c[j]; b[i]=b[j]; } if(b[j]==b[i]) { c[i]=c[j]; b[i]=b[j]+1; } q=1; } } } } for(int i=1;i<=n;i++) { if(b[i]>b[flag]) { flag=i; } } cout<<b[flag]<<endl; if(type==1) { for(int i=1;i<=n;i++) if(b[i]==b[flag]) sum+=c[i]; cout<<sum%123456789; } return 0; }
给我一个巨大的教训。