codeforces 1332D - Walk on Matrix(构造,位运算)

题目大意:

有一个迷宫,小明从左上角可以走到右下角。每次小明走到一个格子,他都可以得到小明当前的分数 按位与 本个格子数字之后的分数。小明初始拿着的分数是:左上角的格子的数。现在有一位参赛者写了一个这样的dp:

很快参赛者bob发现了他的dp是有问题的,现在让你构造一个迷宫,使得bob的dp的输出和最优输出相差k.

k<=1e5. 注意,迷宫里的数字不能超过3e5.

解题思路:

首先,我们必须意识到bob的dp哪里有问题,其实问题就在于bob每一步dp都是贪心取的上一步最优来转移,但其实这在按位与的场景里面是不对的,我们有可能需要的次优的选择来达到全局最优。比如从二进制来看:

假如前一步我们选择了一个更大的数字1,0000 但是很可能我们这一步走的时候遇到了1001. 这样1,0000 & 1001 = 0.

但假如我们前一步选择了次优 1001 那么我们这一步遇到了1001 就会得到一个更优的选项 1001 & 1001 = 1001.

假如,没听懂的话,我们下一步构造就应该了解了。考虑构造这样的一个解:

假设cnt为k的二进制表示的长度.

那么按照bob的走法,输出为0

按照次优的解法输出为k:

比赛的时候m移成了(cnt+1)位,还一直没看出来.....

#include <bits/stdc++.h>
#define int long long 
using namespace std;
int32_t main(){
    int k;cin>>k;
    int tmp=k;
    int cnt=0;
    while(tmp){
        tmp>>=1;
        cnt++;
    }
    int most=(1<<(cnt))+k;
    cout<<3<<" "<<4<<endl;
    cout<<most<<" "<<k<<" "<<most<<" "<<0<<endl;
    cout<<(1<<(cnt) )<<" "<<0<<" "<<most<<" "<< 0<<endl;
    cout<<most<<" "<<most<<" "<<most<<" "<<k<<endl;
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值