徐州邀请赛 江苏 icpc I. T-shirt 矩阵快速幂

本文解析了一道关于寻找最大权值路径的算法题,通过建立动态规划模型并运用矩阵快速幂的方法来求解最优解。适用于解决具有周期性质的最优化问题。

题目

题目描述

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
题目来源

The 2018 ACM-ICPC China JiangSu Provincial Programming Contest

 

题意:有n天,m件衣服,如果某一天穿了第i件衣服,第二天穿了第j件衣服,那么就会获得dp[i][j]的权值。然后给你矩阵f,每件衣服可以穿无限多次,问第n天能获得的最大权值是多少。

分析:设dp[t][i][j]为第1天穿第i件衣服第t天穿第j件衣服时能获得的最大的权值。假设a+b=t显然有dp[t][i][j]=max1km(dp[t][i][j], dp[a][i][k]+dp[b][k][j]),因为牵扯到矩阵所以考虑矩阵快速幂。

参考博客:https://blog.youkuaiyun.com/xs18952904/article/details/80595275

#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define debug(a) cout << #a << " " << a << endl
using namespace std;
const int maxn = 107;
const int mod = 1e9 + 7;
typedef long long ll;
struct matrix {
    ll a[maxn][maxn];
};
ll n, m;
matrix base, ans;
matrix mul( matrix x, matrix y ) {
    matrix tmp;
    memset( tmp.a, 0, sizeof(tmp.a) );
    for( ll i = 0; i < m; i ++ ) {
        for( ll j = 0; j < m; j ++ ) {
            for( ll k = 0; k < m; k ++ ) {
                tmp.a[i][j] = max( tmp.a[i][j], x.a[i][k] + y.a[k][j] );
            }
        }
    }
    return tmp;
}
void qow( ll x ) {
    while( x ) {
        if( x&1 ) {
            ans = mul( ans, base );
        }
        base = mul( base, base );
        x /= 2;
    }
}
int main() {
    std::ios::sync_with_stdio(false);
    while( cin >> n >> m ) {
        memset( ans.a, 0, sizeof(ans.a) );
        for( ll i = 0; i < m; i ++ ) {
            for( ll j = 0; j < m; j ++ ) {
                cin >> base.a[i][j];
            }
        }
        qow( n-1 );
        ll sum = 0;
        for( ll i = 0; i < m; i ++ ) {
            for( ll j = 0; j < m; j ++ ) {
                //cout << ans.a[i][j] << " ";
                sum = max( sum, ans.a[i][j] );
            }
           // cout << endl;
        }
        cout << sum << endl;
    }
    return 0;
}

  

转载于:https://www.cnblogs.com/l609929321/p/9364641.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值