题目描述
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.
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).
输出
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[i][j][k]表示走2^i次,从j->k的最大价值,状态压缩?
然后用了二进制按位与
就是二进制位上都为1的话就说明走了这个,可以递推
n分解成x1*2^p1+x2*2^p2+x3*2^p3.....xn*2^pn
就看xi是不是为1
最后 每一步只与上一步有关 就可以0和1表示
#include <bits/stdc++.h> #define ll long long using namespace std; const int maxn=105; ll s[25][maxn][maxn];//s[a][b][c] b->c 2^a days ll ans[2][maxn][maxn]; int m,n; int main(){ int i,j,l,k; while(cin>>n>>m){ memset(s,0,sizeof(s)); memset(ans,0,sizeof(ans)); for(i=1;i<=m;i++){ for(j=1;j<=m;j++){ cin>>s[0][i][j]; } } for(i=1;i<=20;i++){ for(j=1;j<=m;j++){ for(l=1;l<=m;l++){ for(k=1;k<=m;k++){ s[i][j][l]=max(s[i][j][l],s[i-1][j][k]+s[i-1][k][l]); } } } } n--; int temp=1; for(i=0;i<20;i++){ if(n&(1<<i)){ for(j=1;j<=m;j++){ for(k=1;k<=m;k++){ for(l=1;l<=m;l++){ ans[temp][j][k]=max(ans[temp][j][k],ans[1-temp][j][l]+s[i][l][k]); } } } temp=1-temp; } } temp=1-temp; ll maxx=0; for(i=1;i<=m;i++){ for(j=1;j<=m;j++){ maxx=max(ans[temp][i][j],maxx); } } cout<<maxx<<endl; } return 0; }
这个是状态压缩DP:https://www.cnblogs.com/ibilllee/p/7651971.html