日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多校一道KMP+DP的题

發布時間:2023/12/13 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多校一道KMP+DP的题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

難啊,多校當時根本不會做
?

題目描述

White Cloud has a rectangle carpet of n*m. Grid (i,j) has a color colorA[i][j] and a cost costA[i][j].
White Rabbit will choose a subrectangle B of p*q from A and the color of each grid is colorB[0...p-1][0...q-1], the cost of B is the (maximum number in the corresponding subrectangle of costA*(p+1)*(q+1).
Then colorB is continuously translated and copied in an infinite times, that is, expand colorB into an infinite new matrix, colorC, which satisfies colorC[i][j]=colorB[i mod p][j mod q].
White Rabbit must ensure that colorA is a subrectangle of colorC.
You need to find the minimum cost way.
?

輸入描述:

The first line of input contains two integers n,m(0<n*m <= 1000000) For the next line of n lines, each line contains m lowercase English characters, denoting colorA. For the next line of n lines, each line contains m integers in range [0,1000000000], denoting costA.

輸出描述:

Print the minimum cost.

示例1

輸入

2 5 acaca acaca 3 9 2 8 7 4 5 7 3 1

輸出

18

說明

choose subrectangle colorA[1...1][3...4]=ca, After copying unlimited copiescolorC=cacacacaca ...cacacacaca ...cacacacaca ...cacacacaca ...cacacacaca ............colorA is a subrectangle of colorCthe cost is max(3,1)*(1+1)*(2+1).

?

題目大意:有一個n*m的矩陣A,每個位置有一個字符和一個權值,現在要找一個子矩陣,使得這個子矩陣是A的一個 循環節,并最小化子矩陣的權值最大值。

做法
首先要找到矩陣的一個最小的循環節,假設是p和q,那么最優解就一定是選一個p*q的子矩形。
如何求最小的循環節?行和列可以獨立考慮。 求列的循環節時,我們可以對每一行做一次kmp,找到這些行的最大公共循環節。 求行的循環節時,我們可以對每一列做一次kmp,找到這些列的最大公共循環節。
接下來問題就變成了,求所有大小為p*q的子矩形的最大值的最小值。可以采用單調隊列,求出 所有p*q的子矩形的最大值,然后找一個最小的即可。

?

標程:(肯定不是我寫的哈哈)

#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<assert.h> using namespace std; int gi() {int w;char c;while (((c=getchar())<'0'||'9'<c)&&c!='-');w=c-'0';while ('0'<=(c=getchar())&&c<='9') w=(w<<3)+(w<<1)+c-'0';return w; } const int seed=131; const int mod=1e9+7; const int N=1e6+100; int h[N],L[N],nxt[N]; inline int kmp(int *a,int n) {nxt[0]=0;int i,c,p;for (i=1;i<n&&a[i]==a[i+1];i++);i--;nxt[2]=i;c=2,p=2+nxt[2]-1;if (nxt[2]==n-1) return 1;for (i=3;i<=n;i++) {if (p<i||p-i+1<=nxt[i-c+1]) {nxt[i]=max(p-i+1,0);while (a[nxt[i]+i]==a[nxt[i]+1]) nxt[i]++;if (i+nxt[i]>n) return i-1;c=i,p=i+nxt[i]-1;}else nxt[i]=nxt[i-c+1];}return n; } int Val[N],Q[N]; #define val(x,y) Val[((x)-1)*m+(y)] #define q(x,y) Q[((x)-1)*m+(y)] int l[N],r[N],n,m; int qq[N],w[N]; int key[26]; char s[N]; int main() {int i,j,a,b,ll,rr;char c;int ans=2147483647;n=gi(),m=gi();assert(0<n*m&&n*m<=1e6);for (i=0;i<26;i++) key[i]=rand();for (i=1;i<=n;i++) {scanf("%s",s+1);assert(strlen(s+1)==m);for (j=1;j<=m;j++) {c=s[j];assert('a'<=c&&c<='z');h[i]=(1LL*h[i]*seed+key[c-'a'])%mod;L[j]=(1LL*L[j]*seed+key[c-'a'])%mod;}}a=kmp(h,n);b=kmp(L,m);for (i=1;i<=n;i++) for (j=1;j<=m;j++) val(i,j)=gi(),assert(0<=val(i,j)&&val(i,j)<=1e9);for (i=1;i<=n;i++) l[i]=1,r[i]=0;for (j=1;j<b;j++)for (i=1;i<=n;i++) {while (l[i]<=r[i]&&val(i,j)>=val(i,q(i,r[i]))) r[i]--;q(i,++r[i])=j;}for (j=b;j<=m;j++) {ll=1,rr=0;for (i=1;i<a;i++) {if (l[i]<=r[i]&&q(i,l[i])<=j-b) l[i]++;while (l[i]<=r[i]&&val(i,j)>=val(i,q(i,r[i]))) r[i]--;q(i,++r[i])=j;while (ll<=rr&&val(i,q(i,l[i]))>=qq[rr]) rr--;qq[++rr]=val(i,q(i,l[i])),w[rr]=i;}for (i=a;i<=n;i++) {if (l[i]<=r[i]&&q(i,l[i])<=j-b) l[i]++;while (l[i]<=r[i]&&val(i,j)>=val(i,q(i,r[i]))) r[i]--;q(i,++r[i])=j;if (ll<=rr&&w[ll]<=i-a) ll++;while (ll<=rr&&val(i,q(i,l[i]))>=qq[rr]) rr--;qq[++rr]=val(i,q(i,l[i])),w[rr]=i;ans=min(ans,qq[ll]);}}cout<<1LL*(a+1)*(b+1)*ans<<endl;return 0; }

?

總結

以上是生活随笔為你收集整理的多校一道KMP+DP的题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。