n块垂直放的宽度为1的木板 ,取走一些木板,剩下的按原来次序合在一起。满足 剩下的新图形周长>=原图形周长 ,求取走的木板最大的面积。
DP[i][j] , 剩下的新图形最后一块为第i块,面积为j , 周长为dp[i][j] 。
当j 一定, dp[i][j] 取大为最优。
const int maxn = 58 ;
int a[maxn] ;
int dp[maxn][100*maxn] ;
int father[maxn][100*maxn] ;
bool vis[maxn] ;
int main(){
int n , i , j , k , len , area , t ;
while(cin>>n){
for(i = 1 ; i <= n ; i++) scanf("%d" , &a[i]) ;
a[0] = 0 ;
area = 0 ;
len = 2*n ;
for(i = 1 ; i <= n ; i++){
area += a[i] ;
len += abs(a[i] - a[i-1]) ;
}
len += a[n] ;
memset(father , 0 , sizeof(father)) ;
memset(dp , -1 , sizeof(dp)) ;
dp[0][0] = 0 ;
for(i = 1 ; i <= n ; i++){
for(j = a[i] ; j <= area ; j++){
for(k = 0 ; k < i ; k++){
if(dp[k][j-a[i]] == -1) continue ;
int l = dp[k][j-a[i]] + 2 + 2 * a[i] - 2*min(a[i] , a[k]) ;
if(dp[i][j]==-1 || dp[i][j] < l){
dp[i][j] = l ;
father[i][j] = k ;
}
}
}
}
int li , lj ;
for(i = area ; i >= 0 ; i--){
for(j = 1 ; j <= n ; j++){
if(dp[j][i] == -1) continue ;
if(dp[j][i]*2 >= len){
li = j ;
lj = i ;
}
}
}
memset(vis , 0 , sizeof(vis)) ;
printf("%d\n" , area - lj) ;
if(area - lj != 0){
while(li > 0 && lj > 0){
vis[li] = 1 ;
if(father[li][lj] == 0) break ;
t = father[li][lj] ;
lj -= a[li] ;
li = t ;
}
vector<int> lis ; lis.clear() ;
for(i = 1 ; i <= n ; i++){
if(vis[i] == 0) lis.push_back(i) ;
}
printf("%d\n" , lis.size()) ;
for(i = 0 ; i < lis.size() -1 ; i++) printf("%d " , lis[i]) ;
printf("%d\n" , lis[lis.size()-1]) ;
}
else printf("0\n") ;
}
return 0 ;
}