题目大意:给出一个序列,是由一个长度为n的序列复制T次得到的,问最长非下降子序列的长度。
思路:我们建立一个n*n的矩阵,a[i][j]代表第一段以i为末尾,第二段以j为末尾,拼接起来能增加多少长度,这样只要有一个空的矩阵c,我们让c乘上a^t,记住,这里的乘里面是:c[i][j]=max(c[i][j],a[i][k]*b[k][j]),略微和其他的矩乘不同。然后c里面元素最大那个就是答案。
1 #include2 #include 3 #include 4 #include 5 #include 6 struct Matrix{ 7 int n,r[105][105]; 8 }a,c; 9 int n,T,b[200005];10 int read(){11 int t=0,f=1;char ch=getchar();12 while (ch<'0'||ch>'9'){ if (ch=='-') f=-1;ch=getchar();}13 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}14 return t*f;15 }16 Matrix operator *(Matrix a,Matrix b){17 Matrix c;18 c.n=a.n;19 for (int i=1;i<=a.n;i++)20 for (int j=1;j<=a.n;j++)21 c.r[i][j]=-99999999;22 for (int i=1;i<=a.n;i++)23 for (int j=1;j<=a.n;j++)24 for (int k=1;k<=a.n;k++)25 c.r[i][j]=std::max(c.r[i][j],a.r[i][k]+b.r[k][j]);26 return c; 27 }28 int main(){29 n=read();T=read();30 for (int i=1;i<=n;i++)31 for (int j=1;j<=n;j++)32 a.r[i][j]=c.r[i][j]=0;33 for (int i=1;i<=n;i++) b[i]=read();34 for (int i=1;i<=n;i++)35 for (int j=1;j<=n;j++)36 if (b[i]<=b[j]) {37 a.r[i][j]=1;38 for (int k=1;k