對於矩陣乘法的一些操作 我們 其實 大部分是 多追加乙個係數 或者和 其他演算法連在一起。
至於核心無非就是 先列出dp 方程再優化 或者 直接 對題目進行建模 構建矩陣。
至於矩陣乘法的正確性 形狀的正確性 是可以證明的 但是內部最真實的正確性我還無法證明。
這道題是 字串型別的題目 求方案數 很煩 大部分都是和kmp演算法是連在一起的因為對於不存在當前的子串個個數,就只能kmp的方法尋求方案數了。
設 f[i][j] 表示第乙個字串 匹配到了第i個第二個字元匹配到第j個字元的且不重複的方案數。
那麼此時有狀態轉移 f[i][j]+=f[i-1][k]+g[k][j] 由於這個是字串的匹配 借助kmp演算法 我們是可以求得g陣列的。
然後 有了狀態轉移我們可以 很輕易的 構建出矩陣 f[i]表示第i個字元加上後 已經匹配第二個字串的到第j位方案數 只要沒有匹配到 m位那麼這些狀態都是合法的。
乘上狀態矩陣 g即可。
//#include
#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include
#define inf 2147483646
#define ll long long
#define db double
using namespacestd;char buf[1<<15],*fs,*ft;
inlinechargetc()
while(ch>='0'&&ch<='9')return x*f;
inlinevoid put(intx)
x<0?putchar('-'),x=-x:0;int num=0;char ch[70];while(x)ch[++num]=x%10+'0',x/=10;
num==0?putchar('0'):0;while(num)putchar(ch[num--]);
putchar('\n');return;
}const int maxn=26;intn,m,ans;intmod;charch[maxn];int a[maxn],f[maxn];//f[i]表示第n個數字的第i位所和j匹配的位的方案數
int g[maxn][maxn];//g[i][j] 表示匹配前i的串轉到匹配前j的串的方案數。
intnex[maxn];voidkmp()
nex[1]=0;int j=0;for(int i=2;i<=m;++i)
for(int i=0;i
j=i;while(j&&a[j+1]!=k)j=nex[j];if(a[j+1]==k)++j;if(j
}return;
}structwy
friend wyoperator *(wy a,wy b)
wy tmp;for(int i=0;i
tmp.b[i][j]=(tmp.b[i][j]+(a.b[i][k]*b.b[k][j])%mod)%mod;returntmp;
friend wyoperator -(wy a,wy b)
wy tmp;for(int i=0;i
tmp.f[i]=(tmp.f[i]+(a.f[j]*b.b[j][i])%mod)%mod;returntmp;
friend wyoperator ^(wy a,intp)
wy tmp;tmp.f[0]=1;while(p)
returntmp;
}a;intmain()
while(ch>='0'&&ch<='9')return x*f;
inlinevoidput(ll x)
x<0?putchar('-'),x=-x:0;
ll num=0;char ch[70];while(x)ch[++num]=x%10+'0',x/=10;
num==0?putchar('0'):0;while(num)putchar(ch[num--]);
putchar('\n');return;
}const ll maxn=70;
ll n,m,n,maxx;
ll t,act,nece,rest;//necessary
charch[maxn][maxn],c[maxn][maxn];
ll pos[maxn][maxn],flag[maxn];
ll a[maxn][maxn][maxn];structwy
ll f[maxn];//答案矩陣
ll b[maxn][maxn];//狀態矩陣
wy()
friend wyoperator *(wy a,wy b)
wy tmp;for(ll i=0;i<=n;++i)for(ll j=0;j<=n;++j)for(ll k=0;k<=n;++k)tmp.b[i][j]+=a.b[i][k]*b.b[k][j];returntmp;
friend wyoperator -(wy a,wy b)
wy tmp;for(ll i=0;i<=n;++i)for(ll j=0;j<=n;++j)tmp.f[i]+=a.f[j]*b.b[j][i];returntmp;
friend wyoperator ^(wy a,ll p)
wy tmp;tmp.f[0]=1;while(p)
returntmp;
}a,b;intmain()
freopen("1.in","r",stdin);
n=read();m=read();t=read();act=read();n=n*m;for(ll i=1;i<=n;++i)scanf("%s",ch[i]+1);for(ll i=1;i<=act;++i)
scanf("%s",c[i]+1);
flag[i]=strlen(c[i]+1);
}for(ll i=1;i<=n;++i)for(ll j=1;j<=m;++j)pos[i][j]=(i-1)*m+j;for(ll i=1;i<=n;++i)for(ll j=1;j<=m;++j)
ll target=ch[i][j]-'0'+1;for(ll k=1;k<=60;++k)
ll now=(k-1)%flag[target]+1;if(c[target][now]>='0'&&c[target][now]<='9')
a[k][pos[i][j]][pos[i][j]]=1;
a[k][0][pos[i][j]]=c[target][now]-'0';
}if(c[target][now]=='e'&&j+1<=m)a[k][pos[i][j]][pos[i][j+1]]=1;if(c[target][now]=='w'&&j-1>=1)a[k][pos[i][j]][pos[i][j-1]]=1;if(c[target][now]=='n'&&i-1>=1)a[k][pos[i][j]][pos[i-1][j]]=1;if(c[target][now]=='s'&&i+1<=n)a[k][pos[i][j]][pos[i+1][j]]=1;
nece=t/60;rest=t%60;for(ll k=1;k<=60;++k)
for(ll i=1;i<=n;++i)maxx=max(maxx,a.f[i]);
put(maxx);return 0;
view code
我是清都山水郎,天教分付與疏狂。
矩陣乘法 矩陣乘法的基本實現
求解關於兩個矩陣的乘積 參考線性代數裡面的兩個矩陣相乘的規則,我這裡不再贅述,詳情附上了乙個鏈結,我的程式設計也是用了裡面的例子 這裡寫鏈結內容 具體的過程我會在 片裡面加上注釋 矩陣乘法 author seen 2015 09 18 include using namespace std int ...
矩陣乘法 C
using system using system.collections.generic using system.text namespace exe03 static void main string args int martixb new int int martixc new int m...
Strassen矩陣乘法
strassen矩陣乘法 strassen矩陣乘法是通過遞迴實現的,它將一般情況下二階矩陣乘法 可擴充套件到 階,但strassen矩陣乘法要求 是 的冪 所需的8次乘法降低為7次,將計算時間從o ne3 降低為o ne2.81 矩陣c ab,可寫為 c11 a11b11 a12b21 c12 a1...