JZOJ 1492. 烤饼干

1492. 烤饼干 (Standard IO)

Description

NOIP烤饼干时两面都要烤,而且一次可以烤R(1<=R<=10)行C(1<=C<=10000)列个饼干,当一面烤到规定时间时,机器会把整个翻过来以接着烤另一面。
有一天,正当机器准备翻饼干时发生了地震,有一些饼干被翻了过来,有一些没有。幸运的是,你可以手工操作,一次可以同时翻若干行或者若干列,但不能单独翻某一个饼干。
写一个程序计算通过翻转使得最终翻过来的饼干的数量得最大值。
例如下图是地震之后的情况,黑点表示未翻转,白点表示已经翻转:
翻转第一行后得到:
接着翻转第1列和第5列得到下图:
这样可以使得9个饼干翻转过来。

Input

第1行: 两个整数R和C(1<=R<=10,1<=C<=10000);接下来R行,每行C个空格隔开的数,其中aij=1表示未被翻转,0表示已经翻转。

Output

输出一个整数表示通过翻转行列操作最多被翻转的饼干数量。

Sample Input

2 5
0 1 0 1 0
1 0 0 0 1

Sample Output

9

Data Constraint

Hint

样例输入2:
3 6
1 0 0 0 1 0
1 1 1 0 1 0
1 0 1 1 0 1
样例输出2:
15

题解

状压dp
用f[i][s]来表示第i个反转情况为s时,前i个中1的个数

代码

#include
#define max(a,b) (((a)>(b))?(a):(b))
#define N 10001

long f[2][1<<11],a[N];

int main()
{   long n,m,i,j,s,q,num,ans=0,now;
    scanf("%ld%ld",&n,&m);
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++){
            scanf("%ld",&q);
            a[j]=(a[j]<<1)|q;
        }
    now=0;
    for(i=1;i<=m;i++){
        for(s=0;s<(1<0;
            for(j=0;jif(((1<if((1<else if(!((1<1-now][s]+max(num,n-num);
        }
        now=1-now;
    }
    for(s=0;s<(1<1-now][s]);
    printf("%ld\n",ans);
    return 0;
}

你可能感兴趣的:(动态规划(dp),状压dp)