洛谷P7859 GEPPETTO披萨店

洛谷P7859 [COCI2015-2016#2] GEPPETTO,主要使用了dp和状压

time limit per test:1 second
memory limit per test:64.00MB
input:standard input
output:standard output

题目描述

Geppetto 开了一家披萨店,他正在努力做出全市最好的披萨。

Geppetto 用 N 种原材料做比萨,每种原材料只有一个。原材料标号为 1 到 N。做披萨很简单,只要把原材料混合好然后放进烤箱里烤一烤就行了。但Geppetto 发现一共有 M 对原材料是冲突的,如果一对冲突的原材料混合在一份披萨里,这份披萨就会变得十分难吃。这给他带来了额外的麻烦。

Geppetto 想知道他最多能做多少种不同的比萨。如果一份比萨上有编号为 i 的原材料,而另一份比萨上没有,那么这两份比萨就是不同的。

输入格式

第一行两个整数 ,N,M,分别表示原材料总数和冲突总数。
接下来 M 行,每行两个整数 ,xi,yi ,表示一对冲突中两种原材料的编号。

输出格式

一行一个整数,表示 Geppetto 最多能做多少种披萨。

SAMPLES

input1

3 2
1 2
2 3

output1

5

input2

3 0

output2

8

input3

3 3
1 2
1 3
2 3

output3

4

解题过程

思路:基本过程就是从几个放东西的盒子中取东西,与高中的概率题差不多。注意:可以一个也不取,条件允许的话也可以全取。其中高中的组合数公式Cn0+Cn1+Cn2+…+Cnn=2^n(这里因为还不太熟练用latax,就这样写的)。所以所有情况一共有2 ^n个,也就是1<<n.

代码实现

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define dbug(x) cout << #x << '=' << x << endl
const int N = 400 + 10;
typedef long long ll;
int a[N];
int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= m; i++)
    {
        int l, r;
        cin >> l >> r;
        l--, r--;
        a[i] = (1 << l) | (1 << r);
    }
    int ans = 0;

    for (int i = 0; i < (1 << n); i++)
    {
    //逐个比较从0到n的二进制的数,排除掉a[]里的数
        int flag = 1;
        for (int j = 1; j <= m; j++)
        {
            if ((i & a[j]) == a[j])
            //i&a[j]==a[j]说明i==a[j]
            {
                flag = 0;
                break;
            }
            //如果没有查询到a数组的数,则该方法可行,ans加一
        }
        ans += flag;
    }
    cout << ans << endl;
}


代码解释

  • 这里是把所有情况从0到n用二进制比较了一遍,0|10=11,也就是在a[i]=11时不可以。
  • 第一个for循环中用的或运算:两个位上的数都为0时结果才为0;
  • 对于a[]数组,1<<L=“110^L",1<<R="110 ^R”,两个二进制数进行或运算就得到一个含2个1的二进制数,a[]数组用于储存取的两个数或运算的结果。
  • 第二个for循环了2^n次(1<<n),来依次比较从0到2 ^n的二进制数与a[]是否有重叠,没有的话ans结果就+1,有的话就不加。

总结

将进行的过程转换成二进制数的位运算,依靠0和1来表示状态,再来检查状态。位运算低于比较运算(大于小于等于)低于加减乘除幂运算,第二个for循环内的判断条件!注意各运算的优先级!!!!

  • 28
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XchenPlayer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值