Vladik was bored on his way home and decided to play the following game. He took n cards and put them in a row in front of himself. Every card has a positive integer number not exceeding 8 written on it. He decided to find the longest subsequence of cards which satisfies the following conditions:
- the number of occurrences of each number from 1 to 8 in the subsequence doesn't differ by more then 1 from the number of occurrences of any other number. Formally, if there are ck cards with number k on them in the subsequence, than for all pairs of integers the condition |ci - cj| ≤ 1 must hold.
- if there is at least one card with number x on it in the subsequence, then all cards with number x in this subsequence must form a continuous segment in it (but not necessarily a continuous segment in the original sequence). For example, the subsequence[1, 1, 2, 2] satisfies this condition while the subsequence [1, 2, 2, 1] doesn't. Note that [1, 1, 2, 2] doesn't satisfy the first condition.
Please help Vladik to find the length of the longest subsequence that satisfies both conditions.
The first line contains single integer n (1 ≤ n ≤ 1000) — the number of cards in Vladik's sequence.
The second line contains the sequence of n positive integers not exceeding 8 — the description of Vladik's sequence.
Print single integer — the length of the longest subsequence of Vladik's sequence that satisfies both conditions.
3
1 1 1
1
8
8 7 6 5 4 3 2 1
8
24
1 8 1 2 8 2 3 8 3 4 8 4 5 8 5 6 8 6 7 8 7 8 8 8
17
In the first sample all the numbers written on the cards are equal, so you can't take more than one card, otherwise you'll violate the first condition.
分析:状压dp;
dp[i][j]表示到i为止j里面二进制1表示这个位置的数是否用过的取len+1的个数的最大值;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <queue> #include <stack> #include <vector> #include <list> #define rep(i,m,n) for(i=m;i<=n;i++) #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define Lson L, mid, ls[rt] #define Rson mid+1, R, rs[rt] #define sys system("pause") #define intxt freopen("in.txt","r",stdin) const int maxn=1e3+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} inline void umax(int&p,int q){if(p<q)p=q;} inline ll read() { ll x=0;int f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,k,t,pos[9][maxn],dp[maxn][1<<8],cur[9],a[maxn],ans; bool ok(int len) { memset(dp,-inf,sizeof(dp)); memset(cur,0,sizeof(cur)); dp[1][0]=0; bool flag=false; for(int i=1;i<=n;i++) { for(int j=0;j<(1<<8);j++) { if(dp[i][j]==-inf)continue; for(int k=1;k<=8;k++) { if(j&(1<<(k-1)))continue; if(cur[k]+len>pos[k][0])continue; int now_pos=pos[k][cur[k]+len]; umax(dp[now_pos][j|(1<<(k-1))],dp[i][j]); if(cur[k]+len+1>pos[k][0])continue; now_pos=pos[k][cur[k]+len+1]; umax(dp[now_pos][j|(1<<(k-1))],dp[i][j]+1); } } cur[a[i]]++; } for(int i=1;i<=n+1;i++) { if(dp[i][(1<<8)-1]>=0) { flag=true; ans=max(ans,dp[i][(1<<8)-1]*(len+1)+(8-dp[i][(1<<8)-1])*len); } } return flag; } int main() { int i,j; scanf("%d",&n); rep(i,1,n)a[i]=read(); rep(i,1,n) { pos[a[i]][++pos[a[i]][0]]=i; } rep(i,1,8)if(pos[i][0])ans++; int l=1,r=n/8; while(l<=r) { int mid=l+r>>1; if(ok(mid))l=mid+1; else r=mid-1; } printf("%d ",ans); //system("Pause"); return 0; }