Link: http://acm.zju.edu.cn/onlinejudge/showProblem.do? Problemid = 5334
Question: A series of 500 characters, each of which may be 2, 4, 8, and 16. It is obtained from the first one. You can choose to take or not to take each number. If X is used, if this number is the same as the previous one, the two numbers will be merged into 2 X and collected. If they are different, they will be collected.
Idea: for example, if we want to generate 2048, we must have a 1024,512,256,128, 64, 32, 16, 8, 4, and 2 segment that is continuously decreasing from 1024, then, a number that is the same as the end number can be merged to 2048 consecutively.
Therefore, State compression only requires compression when the status of the record decline sequence exists. DP [I] [J] records the J-condition descent sequence obtained at position I, 1st bits are 2, 2nd bits are 4, 3rd bits are 8 .. (The limit of 500 to 16 is only 8000, so it only needs 12 bits at most, that is, the highest bits 4096, so there are only 4095 cases, because there is no 1 or 0 ). use a binary number to indicate whether these bits are obtained. The key problem is that if the I-th bit is merged, the 1st ~ The I-1 bit is 0, otherwise it is not a continuous decline sequence.
P.s. this question is complicated during the competition. For example, in the case of 2, 2, and 2, I think we need to consider whether to merge the question into 2, 4, or 4, which is actually not required, because automatic merge is performed without a single number, instead of deciding whether to merge.
Code:
#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <ctype.h>#include <iostream>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <vector>#define eps 1e-8#define INF 0x7fffffff#define maxn 10005#define PI acos(-1.0)#define seed 31//131,1313typedef long long LL;typedef unsigned long long ULL;using namespace std;int dp[505][4100];int a[505],Pow[15];map < int,int > M;void init(){ memset(dp,-1,sizeof(dp)); M[2]=1; int pos=2; for(int i=2; i<=12; i++) { pos*=2; M[pos]=i; } return ;}int main(){ int T,tot; scanf("%d",&T); while(T--) { init(); scanf("%d",&tot); for(int i=1; i<=tot; i++) scanf("%d",&a[i]); dp[1][a[1]>>1]=a[1]; for(int i=2; i<=tot; i++) { int dn=(a[i]>>1)-1; dp[i-1][0]=0; for(int j=0; j<4096; j++) { if(dp[i-1][j]>dp[i][j]) dp[i][j]=dp[i-1][j]; if((j&dn)==0&&dp[i-1][j]!=-1) { int ans=0; int k=a[i]>>1; while(1) { if((k&j)==0) break; k*=2; ans+=k*2; } int next=j-(ans>>2)+k; dp[i][next]=max(dp[i-1][j]+ans+a[i],dp[i][next]); } else if((j&dn)!=0&&dp[i-1][j]!=-1) { dp[i][dn+1]=max(dp[i][dn+1],dp[i-1][j]+a[i]); } } } int ans=0; for(int i=0; i<4096; i++) { ans=max(ans,dp[tot][i]); } printf("%d\n",ans); } return 0;}
Zoj 3802 easy 2048 again pressure DP