标签:tin print answer 计算 main can please for lin
题目描述
JSZKC is going to spend his vacation!
His vacation has N days. Each day, he can choose a T-shirt to wear. Obviously, he doesn’t want to wear a singer color T-shirt since others will consider he has worn one T-shirt all the time.
To avoid this problem, he has M different T-shirt with different color. If he wears A color T-shirt this day and B color T-shirt the next day, then he will get the pleasure of f[A][B].(notice: He is able to wear one T-shirt in two continuous days but may get a low pleasure)
Please calculate the max pleasure he can get.
输入
The input file contains several test cases, each of them as described below.
- The first line of the input contains two integers N,M (2 ≤ N≤ 100000, 1 ≤ M≤ 100), giving the length of vacation and the T-shirts that JSZKC has.
- The next follows M lines with each line M integers. The jth integer in the ith line means f[i][j](1<=f[i][j]<=1000000).
There are no more than 10 test cases.
输出
One line per case, an integer indicates the answer
样例输入
3 2
0 1
1 0
4 3
1 2 3
1 2 3
1 2 3
样例输出
2
9
题意:求f[a][b]+f[b][c]+f[c][d]+...+f[p][q](有n-1项)的最大值;
思路:从简单情况入手,当n=2时,求f[a][b]的最大值,两重循环遍历即可;
当n=3时,求f[a][b]+f[b][c]的最大值,三重循环遍历即可;
当n=4时,自然可以四重循环遍历,,,我们换一个角度考虑,可以将f[a][c]的值以f[a][b]+f[b][c]中的最大值替代(得到新的最优的f[1~m][1~m]——此时f[i][j]表示第一天穿i,第三天穿j可以得到的最大快乐),接着求f[a][c]+f[c][d]的最大值,回到n=3的情况,也就是进行三重循环遍历;
当n=5时类似,将f[a][d]以f[a][c]+f[c][d]中的最值替代后,计算f[a][d]+f[d][e]的最值,与此同时,得到新的f[1~m][1~m];
总结一下,相当于不断地更新f[1~m][1~m];一开始f[i][j]表示第1天穿i,第2天穿j的所能得到的最大快乐,更新k次后f[i][j]表示第1天穿i,第2+k天穿j所能得到的最大快乐;
这样的话需要在原始f上更新n-2次得到最终f——f[i][j]表示第一天穿i,第n天穿j所能得到的最大快乐;每一次更新的复杂度为O(m^2),暴力n次更新复杂度O(n*m^2)会超时;
可以将更新视为定义在f上的一种运算‘#‘,f经n-2次更新,可视为f#f#...#f(n-1个f相#),用“快速#”计算n-1个f相#即可;类似于矩阵快速幂;
AC代码:
#include <iostream>
#include<cstdio>
#include<cstring>
typedef long long ll;
using namespace std;
ll n,m;
struct Matrix{
ll f[110][110];
Matrix(){memset(f,0,sizeof(f));}
Matrix operator *(Matrix & mat){
Matrix ret;
for(ll i=1;i<=m;i++){
for(ll k=1;k<=m;k++){
for(ll j=1;j<=m;j++){
ret.f[i][j]=max(ret.f[i][j],mat.f[i][k]+f[k][j]);
}
}
}
return ret;
}
};
Matrix qpow(Matrix a,ll b){
Matrix ret;
while(b){
if(b&1) ret=ret*a;
a=a*a;
b>>=1;
}
return ret;
}
int main()
{
while(scanf("%lld%lld",&n,&m)!=EOF){
Matrix mat;
for(ll i=1;i<=m;i++){
for(ll j=1;j<=m;j++){
scanf("%lld",&mat.f[i][j]);
}
}
mat=qpow(mat,n-1);
ll ans=0;
for(ll i=1;i<=m;i++){
for(ll j=1;j<=m;j++){
ans=max(ans,mat.f[i][j]);
}
}
printf("%lld\n",ans);
}
return 0;
}
[矩阵快速幂]T-shirt(2018江苏邀请赛I题)
标签:tin print answer 计算 main can please for lin
原文地址:https://www.cnblogs.com/lllxq/p/9157343.html