Codeforces_327A(前缀+区间DP)

Codeforces_327A(前缀+区间DP)_第1张图片
Codeforces_327A(前缀+区间DP)_第2张图片

题意

给定一个序列,只有01,必须选定一个区间取反,求最多有几个1


找到一个区间(0的个数减1的个数之差最大),加上之前的的1个数即可

//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ff first
#define ss second
#define ms(x) memset(x,0,sizeof(x))
typedef long long ll;
typedef pair<int,int> pii;
#define inf 0x3f3f3f3f  //10 6110 9567<2^30=10 7374 1824
#define iinf 0x7fffffff //
const int mod=1e9+7;
const int MAX=1e5;
int dp[101][101];
int a[101];
int sum0[101];
int sum1[101];
//第一感觉区间dp,找到一个区间,其0、1个数差最大
//凭感觉AC了,很开心
int main(){
     
    ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
    int n,c=0;
    cin>>n;
    for(int i=1;i<=n;i++){
     
        cin>>a[i];
        sum0[i]=sum0[i-1];//前缀0个数
        sum1[i]=sum1[i-1];//前缀1个数
        if(!a[i])sum0[i]++;
        else{
     
            c++;
            sum1[i]++;
        }
    }
    for(int k=0;k<n;k++){
     
        for(int i=1;i+k<=n;i++){
     
            int j=i+k;
            for(int r=i;r<=j;r++){
     
                dp[i][j]=max(max(dp[i+1][r],dp[i][r]),sum0[j]-sum0[i-1]-sum1[j]+sum1[i-1]);
            }
        }
    }
    if(n==c)cout<<n-1;//特判全1
    else cout<<c+dp[1][n];
}


你可能感兴趣的:(区间DP,动态规划)