codeforces553B. Dima and a Bad XOR DP

本文介绍了一种使用动态规划(DP)解决矩阵中选取元素进行XOR运算问题的方法,通过递推的方式更新状态,确保所选元素的XOR结果严格大于零。文章详细解释了算法思路,并附带完整的C++代码实现。

题目传送门
从矩阵中每一行中选一个数,确定这些数XOR严格大于零


纯暴力的DP,没什么优美可言,因为列的选取没有限制,所以在当前行pos任选一个位置,与所有上一行pos-1中,可以存在XOR值异或就可以了。最后判断除零以外,是否有其他的值存在。
此外,因为要输出顺序,所以再开一个数组,记录在行pos上,到达值i时,加入的列,再根据异或的自反性 a XOR a =0,倒退回去即可。


#include <stdio.h>
#include <climits>
#include <cstring>
#include <time.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <vector>
#include <string>

#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return

#define getLen(name,index) name[index].size()
#define mem(a,b) memset(a,b,sizeof(a))
#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;

int N,M;
int store[505][505];
bool dp[500][1050];
int pre[500][1050];
vector<int> ans;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int kind=0;
    cin>>N>>M;
    rep(i,0,N){
        rep(j,0,M){
            cin>>store[i][j];
        }
    }

    rep(i,0,M){
        dp[0][store[0][i]]=true;
        pre[0][store[0][i]]=i;
    }
    rep(i,1,N){
        rep(j,0,M){
            int num=store[i][j];
            rep(k,0,1024){
                if(dp[i-1][k]){
                    pre[i][k^num]=j;
                    dp[i][k^num]=true;
                }
            }
        }
    }

    bool f=false;
    rep(i,1,1024){
        if(dp[N-1][i]){
            f=true;

            int num=i;
            drep(pos,N-1,0){
                ans.Push(pre[pos][num]);
                num=num ^ store[pos][pre[pos][num]];
            }

            break;
        }
    }

    if(!f){
        cout<<"NIE"<<endl;
    }else{
        cout<<"TAK"<<endl;
        drep(i,ans.size()-1,0)
            cout<<ans[i]+1<<" ";
        cout<<endl;
    }

    re 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值