解法
DPる。但し普通に配列をとると逝ったので、やめよう(戒め)偶奇で分けるdp[今の位置][A][Aの個数+1] = min(dp[前の位置][A][Aの個数],dp[前の位置][B][Aの個数] + data[今]);
dp[今の位置][B][Aの個数] = min(dp[前の位置][B][Aの個数],dp[前の位置][A][Aの個数] + data[今]);
で幸せになれた(切実)
ソース
#include<iostream>
#include<algorithm>
using namespace std;
#define INF ( 1 << 30 )
int dp[2][2][5001],data[9999];
int main(){
int n;
cin >> n;
fill_n(**dp,2*2*5001,INF);
dp[0][0][0] = 0;
for(int i = 1 ; i < n ; i++ ){
cin >> data[i];
}
for(int i = 0 ; i < n ; i++ ){
for(int j = 0 ; j <= min(n/2,i) ; j++ ){
dp[(i+1)&1][0][j+1] = min(dp[i&1][0][j],dp[i&1][1][j]+data[i]);
dp[(i+1)&1][1][j] = min(dp[i&1][1][j],dp[i&1][0][j]+data[i]);
}
dp[(i+1)&1][0][0] = INF;
}
cout << min(dp[(n/2)%2][0][n/2],dp[(n/2)%2][1][n/2]) << endl;
}
0 件のコメント:
コメントを投稿