转载请注明出处,谢谢http://blog.youkuaiyun.com/ACM_cxlove?viewmode=contents by---cxlove
A:模拟,然后判断
B:枚举起点,然后二分最远的。或者维护两个指针
C:预处理出up[i],down[i]
up[i]表示从i开始,非递减到最远的位置
down[i]表示从i往前,非递减到最远的位置
那么对于某个区间[l,r]只要up[i]<down[i],说明中间还有段区间,否则为YES
D:状态压缩DP。
对于某一个状态,最高位上的1,说明当前需要用低位相加凑出来。
所有低位上为1表示当前已经有这个数,否则没有
递归,记忆化DP,路径上所有状态包含1个数的最大值便是解,找到最优解就行了
int n;
int a[23];
int dp[1<<23];
int s[1<<23];
int dfs(int state){
if(dp[state]<inf)
return dp[state];
int ans=inf;
for(int i=n-1;i>=0;i--){
if(state&(1<<i)){
int pre=state^(1<<i);
for(int j=0;j<i;j++)
for(int k=0;k<i;k++){
if(a[j]+a[k]==a[i]){
int cur=pre;
cut=cur|(1<<j)|(1<<k)|(1<<(i-1));
ans=min(ans,max(dfs(cur),s[cur]));
}
}
break;
}
}
return dp[state]=ans;
}
int main(){
for(int i=1;i<(1<<23);i++)
s[i]=s[i>>1]+(i&1);
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
if(n==1){
cout<<1<<endl;
return 0;
}
mem(dp,0x3f);
dp[1]=0;
dp[0]=0;
dfs(1<<(n-1));
cout<<(dp[1<<(n-1)]>=inf?-1:dp[1<<(n-1)])<<endl;
return 0;
}
E:DP,有两种情况
某位是1,在高位为+,然后在低位为-
所以dp[0][i]表示当前位为+,dp[1][i]表示当前位处于第二种情况
显然的骗访问,呵呵~~~