赞
踩
对这个题意我再做一点说明,本题求的最大值是这样算的:选一个原序列的子集,然后这个子集你可以任意排序,成为一个序列,对于这个序列你可以翻转单个元素,然后就是这个的最大值。
n n n很小,颜色数更小,考虑暴力 d p dp dp,设 f [ i ] [ j ] [ x ] [ y ] f[i][j][x][y] f[i][j][x][y]为在区间 [ i , j ] [i,j] [i,j]选子集,组成序列两边的颜色为 x , y x,y x,y,转移方法如下:
时间复杂度 O ( 4 3 × n 3 ) O(4^3\times n^3) O(43×n3),贴个代码。
#include <cstdio> #include <cstring> #include <iostream> using namespace std; int read() { int x=0,flag=1;char c; while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1; while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar(); return x*flag; } int n,ans,f[105][105][5][5]; int main() { memset(f,-0x3f,sizeof f); n=read(); for(int i=1;i<=n;i++) { int x=read(),c=read(),y=read(); f[i][i][x][y]=f[i][i][y][x]=c; } for(int i=n;i>=1;i--) for(int j=i;j<=n;j++) for(int x=1;x<=4;x++) for(int y=1;y<=4;y++) { for(int k=i;k<j;k++) { f[i][j][x][y]=max(f[i][j][x][y],max(f[i][k][x][y],f[k+1][j][x][y])); f[i][j][x][y]=max(f[i][j][x][y],max(f[i][k][y][x],f[k+1][j][y][x])); for(int p=1;p<=4;p++) { f[i][j][x][y]=max(f[i][j][x][y],max(f[i][k][x][p],f[i][k][p][x])+max(f[k+1][j][p][y],f[k+1][j][y][p])); } } ans=max(ans,f[i][j][x][y]); } printf("%d\n",ans); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。