5.23杂题选讲

咕了不知道多久的杂题选讲终于回来了2333

然而这次讲的5题里面2题写过2题口胡过,还有一题是sb题???

不管了,作业还是要交的。

洛谷P5369 最大前缀和

做过啦2333

考虑到一个最大前缀和必然由两个部分组成:第一个是任意一个后缀都大于等于0,第二个是任意一个前缀都小于0。

然后随便状压一下就做完了。

#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
    using namespace std;
    #define pii pair<int,int>
    #define fir first
    #define sec second
    #define MP make_pair
    #define rep(i,x,y) for (int i=(x);i<=(y);i++)
    #define drep(i,x,y) for (int i=(x);i>=(y);i--)
    #define go(x) for (int i=head[x];i;i=edge[i].nxt)
    #define templ template<typename T>
    #define sz 1100000
    #define mod 998244353ll
    typedef long long ll;
    typedef double db;
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
    templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
    templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
    templ inline void read(T& t)
    {
        t=0;char f=0,ch=getchar();double d=0.1;
        while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
        while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
        if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
        t=(f?-t:t);
    }
    template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
    char __sr[1<<21],__z[20];int __C=-1,__zz=0;
    inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
    inline void print(register int x)
    {
        if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
        while(__z[++__zz]=x%10+48,x/=10);
        while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
    }
    void file()
    {
        #ifdef NTFOrz
        freopen("a.in","r",stdin);
        #endif
    }
    inline void chktime()
    {
        #ifndef ONLINE_JUDGE
        cout<<(clock()-t)/1000.0<<'\n';
        #endif
    }
    #ifdef mod
    ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
    ll inv(ll x){return ksm(x,mod-2);}
    #else
    ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
    #endif
//  inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n;
int a[25];
int sum[sz];
ll f[sz],g[sz];

ll fac[sz];
void init(){fac[0]=1;rep(i,1,sz-1) fac[i]=fac[i-1]*i%mod;}

int main()
{
    file();
    init();
    read(n);
    rep(i,1,n) read(a[i]);
    int N=(1<<n)-1;
    rep(i,0,N) rep(j,0,n-1) if (i>>j&1) sum[i]+=a[j+1];
    g[0]=1;
    rep(i,0,N-1) 
        rep(j,1,n) 
            if (!(i>>(j-1)&1)&&sum[i|(1<<(j-1))]<0) 
                (g[i|(1<<(j-1))]+=g[i])%=mod;
    rep(i,0,n-1) f[1<<i]=1;
    rep(i,1,N-1) 
        if (sum[i]>=0)
            rep(j,0,n-1) 
                if (!(i>>j&1))
                    (f[i|(1<<j)]+=f[i])%=mod;
    ll ans=0;
    rep(i,1,N) (ans+=f[i]*g[N^i]%mod*sum[i]%mod)%=mod;
    cout<<(ans+mod)%mod;
    return 0;
}

CF1163D Mysterious Code

没做过,然而是sb题。

直接\(dp_{i,j,k}\)表示\(c\)的前\(i\)位,匹配到\(s\)的前\(j\)位、\(t\)的前\(k\)位,配上kmp直接转移就可以AC了。

但是好像还是可以优化:假设\(j\ge k\),则\(k\)完全没有用,可以经过预处理后被\(j\)表示出来。

所以可以记\(dp_{i,p,0/1}\)表示\(c\)的前\(i\)位,\(p\)\(j\)还是\(k\),然后乱转移?

(网上没有这样的题解,不保证正确性,然而感觉挺对)

CF1139E Maximize Mex

口胡过啦。

很容易想到暴力的二分图匹配:左边权值右边社团,随便搞。

然而你会发现这样过于暴力:删了人会冒出一个洞,之后要用很长的时间重新搞到答案。

于是考虑反过来加人:这样答案就可以一路往前推,直接匈牙利算法即可。

代码咕咕咕。

洛谷P3239 [HNOI2015]亚瑟王

做过啦。

容易想到期望的线性性:考虑每一张牌被发动的概率。

然后这题有一点奇怪:不是按轮来DP而是把所有轮压在一起DP。

(或许是我孤陋寡闻?)

\(f_i\)表示第\(i\)张牌在所有的\(r\)轮中被打出的概率,\(dp_{i,j}\)表示在所有的\(r\)轮中,前\(i\)张牌打出了\(j\)张的概率。

然后随便转移即可。

(代码去年暑假写的,可能较丑)

#include<bits/stdc++.h>
#define sz 300
using namespace std;
double ksm[sz][sz];
double p[sz];
double dp[sz][sz];
double fp[sz];
int d[sz],n,r;
void work()
{
    #define mem(a,val) memset(a,val,sizeof(a)) 
    mem(ksm,0);mem(p,0);mem(d,0);mem(dp,0);mem(fp,0);
    scanf("%d %d",&n,&r);
    int i,j;
    for (i=1;i<=n;i++) scanf("%lf %d",&p[i],&d[i]);
    for (i=1;i<=n;i++)
    {
        ksm[i][0]=1;
        for (j=1;j<=r;j++) ksm[i][j]=(1.0-p[i])*ksm[i][j-1];
    }
    dp[1][0]=ksm[1][r];dp[1][1]=1.0-ksm[1][r];
    dp[0][0]=1;
    for (i=2;i<=n;i++)
    {
        for (j=0;j<=min(i,r);j++)
        {
            if (i!=j) dp[i][j]=dp[i-1][j]*ksm[i][r-j];
            if (j) dp[i][j]+=dp[i-1][j-1]*(1.0-ksm[i][r-j+1]);
        }
    }
    double ans=0;
    for (i=1;i<=n;i++)
        for (j=0;j<=min(i-1,r);j++)
            fp[i]+=dp[i-1][j]*(1.0-ksm[i][r-j]);
    for (i=1;i<=n;i++) ans+=d[i]*fp[i];
    printf("%.10lf\n",ans);
}
int main()
{
    int T;
    scanf("%d",&T);
    while (T--) work();
}

洛谷P5376 [THUPC2019]过河卒二

有趣的一道题。

发现某些格子不能经过非常恶心,考虑容斥把它搞掉。

钦定一些点必须被走过,然后转化为\((0,0)\)走到\((n,m)\)的方案数和走出\(n\times m\)的矩阵的方案数。

\((0,0)\)走到\((n,m)\)可以枚举有多少个斜向上走的步数,那么可以求出向右和向上的步数,组合数求出方案数即可。

走出去的方案数呢?有一个很棒的东西:这东西等价于走到\((n+1,m+1)\)的方案数,证明显然。

那么先处理出这些东西,然后容斥即可。

代码咕咕咕。

转载于:https://www.cnblogs.com/p-b-p-b/p/10943410.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要安装Keil 5.23并使用ARM9微控制器,您需要按照以下步骤进行操作: 1. 首先,您需要下载Keil 5.23软件安装包。您可以在Keil官方网站上找到最新版本的软件,并选择与您的操作系统相匹配的版本进行下载。 2. 下载完成后,双击安装包文件并按照提示进行安装。请确保您具有管理员权限以完成安装。 3. 在安装过程中,您将需要选择适合您的开发环境和预期用途的安装选项。请确保选择与ARM9微控制器兼容的选项和工具链。 4. 完成安装后,启动Keil 5.23软件。您将看到一个初始界面,该界面是Keil的集成开发环境(IDE)。 5. 接下来,您需要创建一个新的项目或打开一个现有项目。如果您是初学者,建议您选择创建一个新的项目,以便您可以从头开始配置和编程。 6. 创建新项目后,您需要选择正确的微控制器型号。对于ARM9微控制器,您需要在设备列表中找到适合您的型号,并将其添加到项目中。 7. 完成设备选择后,您可以开始编写和调试代码。Keil提供了一套强大的工具,包括C编译器、调试器等,以帮助您进行代码开发和调试。 8. 完成代码开发后,您可以在Keil IDE中构建和下载程序到ARM9微控制器上。请确保您的目标设备与计算机连接,并正确配置IDE中的调试设置。 9. 最后,您可以通过Keil提供的调试工具进行代码调试和性能分析。这些工具可以帮助您定位和解决程序中的错误和性能问题。 10. 完成上述步骤后,您的ARM9开发环境就准备好了,您可以开始开发自己的项目并运行在ARM9微控制器上。 希望上述步骤对您有所帮助,并使您能够成功地安装和配置Keil 5.23以用于ARM9微控制器开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值