码迷,mamicode.com
首页 > 其他好文 > 详细

[矩阵快速幂]T-shirt(2018江苏邀请赛I题)

时间:2018-06-08 20:41:15      阅读:691      评论:0      收藏:0      [点我收藏+]

标签: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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!