德玛西亚万岁

简介: 【7月更文挑战第2天】

德玛西亚万岁


题意:n*m的矩阵 1能站人,0不能站人,相邻的地方不能站人,问总方案数?


题解:知识点状态DP.
通过题意我们可以知道:
1,当位置(i,j)为0时,不能站人。
2,如果(i,j)站人,那么[i-1,j],[i+1,j],[i,j+1],[i,j-1]这四个地方不能站;
因为数据量不是很大所以我们可以想到用二进制来表示当前该位置上是否站人。
针对1,我们可以样做,因为那这个位置不能站人,所以他这个为对应的二进制位为0,这样之后判断就可以知道,这个位置可不可以站人了。
针对2,我们先看左右的,由于我们把能不能站人转化成了二进制,那么我们也可以用二进制来表示那些位置上站没站人,然后利用错位来判断是否有相邻的,例如
1010101//原本的二进制 101010//错位之后的二进制 0000000//比较之后
比较之后如果是零就说明他没有相邻的。而如果有相邻的就是这种情况
11011000//原 01101100//错 01001000//结果
我们可以知道前一对11和后一对11他们是相邻的 所以返回值不是0;

然后我们看上下:其实就是在枚举一遍上一层的二进制站位,原理跟左右一样,就是这一层是上一层继承过来的,所以若果没有相邻的也要加上上层的那个状态,
最后不要忘了,一个都不放 也是一种方案;

代码:

#include <map>
#include <queue>
#include <string>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <math.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
typedef pair<ll,ll> pii;
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl;
#define rep(i,n) for(int i=0;i<(n);++i)
#define repi(i,a,b) for(int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(int i=int(b);i>=(a);--i)
const int maxn=2e5+1010;
#define inf 0x3f3f3f3f
#define sf scanf
#define pf printf
const int mod=100000000;
const int MOD=10007;

inline int read() {
   
    int x=0;
    bool t=false;
    char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}

/*priority_queue<ll , vector<ll> , greater<ll> > mn;//上  小根堆         小到大 
priority_queue<ll , vector<ll> , less<ll> > mx;//下       大根堆      大到小
map<ll,ll>mp;*/

ll n,m,t,l,r,p;
ll sum,ans,res,cnt,flag,maxx,minn;
bool isprime[maxn];
ll a[maxn],b[maxn],c[maxn];
ll dis[maxn],vis[maxn];
ll dp[20][1<<16];
string str,s;

#define read read()
int main(){
       
     while(~scanf("%lld%lld",&n,&m)){
   
        p=(1<<m);//总的二进制方案数
        //每次初始化
        for(int i=1;i<=n;i++) dis[i]=0;
        for(int i=0;i<=n;i++)
            for(int j=0;j<p;j++) 
                dp[i][j]=0;

        dp[0][0]=1;//什么都不放也算一种方案数
        for(int i=1;i<=n;i++)
            for(int j=0;j<m;j++){
   
                cin>>l;
                dis[i]=dis[i]|(l<<j);//判断这一个位置有没有 用二进制表示
            }


        for(int i=1;i<=n;i++){
               
            for(int j=0;j<p;j++){
   //用二进制表示当前的状态
                //没有这种状态
                if((j&dis[i])!=j)continue;

                //左右相邻了
                if(j&(j>>1))continue;

                for(int k=0;k<p;k++){
   
                    if(k&j) continue;//上下相邻了 
                    else dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;//可以从上层转移过来
                }
            }
        }
        ans=0;
        for(int i=0;i<p;i++){
   
            ans=(ans+dp[n][i])%mod;
        }
        cout<<ans<<endl;



    }
    return 0;
}

扑克牌


题意:给你n种牌,并给你这n种牌的张数,再给你m张万能牌,让你求最多配出多少套牌(就是n中 种牌,一种一张)

题解:知识点:二分
从整体上来看,配出的多少套牌是单调的,想到二分。
重点说一下check判断函数吧,因为你二分出来结果是,一定要判断结果是否符合,如果你配x套,需要大于m张万能牌,那么这样肯定是不行的,再者一套牌中有两张万能牌也是不符合题意的,所以生成了这两个判断条件。

注意一下:他的右端不要设5e8,我当时就看到他给的范围是5e8我就设的5e8,这样想一下,如果n种牌都有5e8,再有5e8个万能牌,会怎样?当然结果就不在5e8范围内了。所以最右端应该是2*5e8。因为一套牌最多有一个万能牌,所以配出来的,最多加上n种牌数量最多的那个个数。也就是5e8+5e8喽。

代码:

#include <map>
#include <queue>
#include <string>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <math.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
typedef pair<ll,ll> pii;
#define mem(a,x) memset(a,x,sizeof(a))
#define debug(x) cout << #x << ": " << x << endl;
#define rep(i,n) for(int i=0;i<(n);++i)
#define repi(i,a,b) for(int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(int i=int(b);i>=(a);--i)
const int maxn=2e5+1010;
#define inf 0x3f3f3f3f
#define sf scanf
#define pf printf
const int mod=998244353;
const int MOD=10007;

inline int read() {
   
    int x=0;
    bool t=false;
    char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}

/*priority_queue<ll , vector<ll> , greater<ll> > mn;//上  小根堆         小到大 
priority_queue<ll , vector<ll> , less<ll> > mx;//下       大根堆      大到小
map<ll,ll>mp;*/

ll n,m,t,l,r,p;
ll sum,ans,res,cnt,flag,maxx,minn;
bool isprime[maxn];
ll a[maxn],b[maxn],c[maxn];
ll dis[maxn],vis[maxn];
ll dp[1010][1010];
string str,s;

bool check(ll x){
   
    ll sum=0;
    for(int i=1;i<=n;i++)
        if(a[i]<x) sum+=x-a[i];
    if(sum>min(x,m)) return 0;
    else return 1;
}
#define read read()
int main(){
   
     cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    l=0,r=1e9+10;
    while(l<=r){
   
        ll mid=(l+r)/2;
        if(check(mid)){
   
            ans=mid;
            l=mid+1;
        }else r=mid-1;
    }
    cout<<ans<<endl;
    return 0;
}
目录
相关文章
|
存储 Java Spring
SpringBoot 如何使用 @ControllerAdvice 注解处理异常消息
SpringBoot 如何使用 @ControllerAdvice 注解处理异常消息
|
前端开发 JavaScript IDE
ESLint 是如何使用和实现的?
前言 今天这篇文章,主要聊聊什么是ESLint,为什么要用它?它的实现原理是什么?工作中如何使用的ESLint,以及如何自定义ESLint规则。 本文整理自以下文章: • 掘金:eslint工作原理探讨 • 手摸手教你写eslint插件 • 慕课网:《大前端》第七周「团队协作」
435 0
|
3天前
|
弹性计算 运维 搜索推荐
三翼鸟携手阿里云ECS g9i:智慧家庭场景的效能革命与未来生活新范式
三翼鸟是海尔智家旗下全球首个智慧家庭场景品牌,致力于提供覆盖衣、食、住、娱的一站式全场景解决方案。截至2025年,服务近1亿家庭,连接设备超5000万台。面对高并发、低延迟与稳定性挑战,全面升级为阿里云ECS g9i实例,实现连接能力提升40%、故障率下降90%、响应速度提升至120ms以内,成本降低20%,推动智慧家庭体验全面跃迁。
|
4天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
369 91
|
5天前
|
SQL 人工智能 自然语言处理
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
随着生成式AI的普及,Geo优化(Generative Engine Optimization)已成为企业获客的新战场。然而,缺乏标准化流程(Geo优化sop)导致优化效果参差不齐。本文将深入探讨Geo专家于磊老师提出的“人性化Geo”优化体系,并展示Geo优化sop标准化如何帮助企业实现获客效率提升46%的惊人效果,为企业在AI时代构建稳定的流量护城河。
384 156
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
|
5天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
4天前
|
数据采集 缓存 数据可视化
Android 无侵入式数据采集:从手动埋点到字节码插桩的演进之路
本文深入探讨Android无侵入式埋点技术,通过AOP与字节码插桩(如ASM)实现数据采集自动化,彻底解耦业务代码与埋点逻辑。涵盖页面浏览、点击事件自动追踪及注解驱动的半自动化方案,提升数据质量与研发效率,助力团队迈向高效、稳定的智能化埋点体系。(238字)
267 156