感觉早些年IOI的题都不难啊,也就NOIp难度……现在貌似变难了
状态用dp[n][a1][b1][a2][b2]表示
n表示处理到前n个餐车
第一组矿工得到的最近一种食物用a1表示,a1的上一种食物用b1表示,第二组矿工的用a2和b2表示
a和b的取值范围为[0,3],0表示没有食物,1~3分别表示三种食物中的一种
第一维可以用滚动数组优化空间
#include <cstdio> #include <cstring> #include <algorithm> ; ][][][][]; //none=0,bread=1,meat=2,fish=3 int N; char seq[maxN]; int s[maxN]; inline int code(char x) { switch(x) { ; ; ; } ; //unused } void input() { scanf("%d",&N); scanf("%s",seq); ;i<N;i++) s[i]=code(seq[i]); } inline int val(int cur,int last1,int last2) { ) :; :; :; } int solve() { memset(dp[],])); dp[][s[]][][][]=dp[][][][s[]][]=; ;i<N;i++) { int& v=s[i]; memset(dp[],])); ;a1<;a1++) { if(!a1) { //b1=0 ;a2<;a2++) ;b2<;b2++) { dp[][v][][a2][b2]=std::max (dp[][v][][a2][b2], dp[][][][a2][b2]+); dp[][][][v][a2]=std::max (dp[][][][v][a2], dp[][][][a2][b2]+val(v,a2,b2)); } } ;b1<;b1++) ;a2<;a2++) { if(!a2) { dp[][a1][b1][v][]=std::max (dp[][a1][b1][v][], dp[][a1][b1][][]+); dp[][v][a1][][]=std::max (dp[][v][a1][][], dp[][a1][b1][][]+val(v,a1,b1)); } ;b2<;b2++) { dp[][v][a1][a2][b2]=std::max (dp[][v][a1][a2][b2], dp[][a1][b1][a2][b2]+val(v,a1,b1)); dp[][a1][b1][v][a2]=std::max (dp[][a1][b1][v][a2], dp[][a1][b1][a2][b2]+val(v,a2,b2)); } } } memcpy(dp[],dp[],])); } ; ;a1<;a1++) ;b1<;b1++) ;a2<;a2++) ;b2<;b2++) ans=std::max(ans,dp[][a1][b1][a2][b2]); return ans; } int main() { input(); printf("%d\n",solve()); ; }