首页 > 其他分享 >考试总结

考试总结

时间:2024-09-18 15:47:40浏览次数:1  
标签:总结 10 ch int long dp 考试 define

DP专题考试

这几天考了很多场DP啊,属实是考废了,中途因为唐氏错误保龄了一次,其他几次考的也不是很理想,可能跟最近低迷的状态有关吧。

现在开学停课搞竞赛,先把前几天的DP总结一下。

Day1(2024.8.30)

T1 天平(balance)

题意

有一个杠杆,有若干个秤砣,重量为 \(w_i\),和若干个可以放置秤砣的位置 \(p_i\),求在使用所有秤砣的条件下,有多少种挂秤砣的方案,可以使杠杆平衡(力矩之和为0)。

思路

我们考虑 \(dp_{i,j}\) 表示的是放了前 \(i\) 个秤砣,当前力矩为 \(j\) 的方案数。

对于当前秤砣 \(i\),它放到第 \(j\) 个可以放的位置的力矩为 \(w_i \times p_j\)。

那么就能得到:

\[dp_{i,j}=dp_{i-1,j-w_i \times p_j}+dp_{i,j} \]

再看一眼限制:

\(n,m \le 20\)

直接秒了(为什么时间如此充裕)。

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define PII pair<int,int>
#define mk(a,b) make_pair(a,b)
using namespace std;
template<typename P>
inline void read(P &x){
    P res=0,f=1;
    char ch=getchar();
    while(ch<'0' || ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9'){
        res=(res<<3)+(res<<1)+(ch^48);
        ch=getchar();
    }
    x=res*f;
}
template<typename PP>
inline void write(PP x){
    if(x<0) putchar('-'),x=-x;
    if(x>=10) write(x/10);
    putchar('0'+x%10);
}
int T=1;

int n,m;
int w[22],s[22],co[22][22];
unordered_map<int,int> dp[22];//前i个力举之和为j

signed main(){
    auto solve=[&](){
        read(n),read(m);
        for(int i=1;i<=n;++i) read(s[i]);
        for(int i=1;i<=m;++i) read(w[i]);
        for(int i=1;i<=m;++i){
            for(int j=1;j<=n;++j){
                co[i][j]=s[j]*w[i];
            }
        }
        dp[0][0]=1;
        for(int i=1;i<=m;++i){
            for(int j=-10000;j<=10000;++j){
                for(int k=1;k<=n;++k){
                    dp[i][j]=dp[i-1][j-co[i][k]]+dp[i][j];
                } 
            }
        }
        cout<<dp[m][0]<<endl;
    };
    freopen("balance.in","r",stdin);
    freopen("balance.out","w",stdout);
    // read(T);
    while(T--) solve();
    return 0;
}

T2 山峰数(hill)

题意

山峰数是指数字排列中不存在山谷(先降后升)的数,例如 0,5,13,12321 都是山峰数,101,1110000111 都不是山峰数。

现给出 n 个数,请依次判断它们是否为山峰数,如果不是,输出-1。如果是,求出比它小的数中有多少个山峰数。

思路

简单数位DP,因为要考虑之前是否下降过,所以在转移过程过添加一维 \(flag\) 表示之前是否已经下降过了,然后还需要一维前缀 \(pre\)。

填数字的时候只需要判断一下是否 \(flag\) 并且当前填的数比前缀 \(pre\) 大,如果是,则跳过,否则搜索。

如果当前是下降的,把 \(flag\) 设为 \(1\) 即可,其余情况不变。

其实数位DP用记忆化搜索好理解多了。

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define PII pair<int,int>
#define mk(a,b) make_pair(a,b)
using namespace std;
template<typename P>
inline void read(P &x){
    P res=0,f=1;
    char ch=getchar();
    while(ch<'0' || ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9'){
        res=(res<<3)+(res<<1)+(ch^48);
        ch=getchar();
    }
    x=res*f;
}
template<typename PP>
inline void write(PP x){
    if(x<0) putchar('-'),x=-x;
    if(x>=10) write(x/10);
    putchar('0'+x%10);
}
int T=1;

char a[72];
int n;
int num[72];
int f[72][72][2];

int dfs(int now,bool op0,bool lim,int pre,bool flag){
    if(!now) return 1;
    if(!op0 && !lim && f[now][pre][flag]!=-1) return f[now][pre][flag];
    int up=lim?num[now]:9,res=0;
    for(int i=0;i<=up;++i){
        if(flag && i<=pre) res+=dfs(now-1,(op0 && i==0),(lim && i==up),i,1);
        else if(!flag) res+=dfs(now-1,(op0 && i==0),(lim && i==up),i,(i<pre));
    }
    if(!op0 && !lim) f[now][pre][flag]=res;
    return res;
}

signed main(){
    memset(f,-1,sizeof(f));
    auto solve=[&](){
        cin>>(a+1);
        n=strlen(a+1);
        bool down=0;
        for(int i=1;i<=n;++i) num[i]=a[i]-'0';
        for(int i=1;i<n;++i){
            if(num[i]<num[i+1] && down){
                cout<<-1<<endl;
                return;
            }
            if(num[i]>num[i+1]) down=1;
        }
        reverse(num+1,num+n+1);
        cout<<dfs(n,1,1,0,0)-1<<endl;
    };
    freopen("hill.in","r",stdin);
    freopen("hill.out","w",stdout);
    read(T);
    while(T--) solve();
    return 0;
}

T3 粉刷匠 2(draw)

题意

\(4 \times n\) 的矩阵,有 256 种颜色,每个位置都可以选择一种颜色。

现在要满足以下条件:

  1. \(A(x,y) \ge A(x,y-1)\)
  2. 有一些指定的 \((x1,y1)\) 和 \((x2,y2)\),要求 \(A(x1,y1)=A(x2,y2)\)

求方案数,只输出答案后 5 位。

思路

比较有意思的背包。

我们不按照常规思维枚举行列,而是从小到大枚举颜色。若当前枚举到的颜色为 \(i\),我们使用 \(dp[l1][l2][l3][l4]\) 表示每一行使用当前颜色涂到哪一个位置。

假设有一行现在是 123344556,现在涂 7,显然涂 7 只能涂序列的后缀,比如涂成 123777777,或者 123344577 才能符合条件。所以考虑枚举当前颜色涂到哪个后缀来转移,转移时同样需要使用完全背包的降维思想优化。

对于限制条件,我们需要把不符合限制条件的去掉,什么样的方案符合限制条件呢?对于限制条件 \(A(x1,y1) = A(x2,y2)\),和当前枚举到的颜色 \(i\),要么 \(x1\) 行和 \(x2\) 行,当前颜色都涂到了 \(y1,y2\) 位置,要么都没有涂到 \(y1,\) 位置。除此之外的都是不合法的方案,我们事先处理好一个 \(vis\) 数组,\(vis[l1][l2][l3][l4]\) 表示四行分别涂到 \(l1,l2,l3,l4\),是否可行,在 dp 时如果遇到标记不可行的 \(vis\),这 dp 值设为 \(0\) 即可。

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define PII pair<int,int>
#define mk(a,b) make_pair(a,b)
using namespace std;
template<typename P>
inline void read(P &x){
    P res=0,f=1;
    char ch=getchar();
    while(ch<'0' || ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9'){
        res=(res<<3)+(res<<1)+(ch^48);
        ch=getchar();
    }
    x=res*f;
}
template<typename PP>
inline void write(PP x){
    if(x<0) putchar('-'),x=-x;
    if(x>=10) write(x/10);
    putchar('0'+x%10);
}
int T=1;

const int mod=100000;

int n,m,tc=1;
int c[4];
int f[16][16][16][16];
bool vis[16][16][16][16];
int r1x[105],r2x[105],r1y[105],r2y[105];

signed main(){
    auto solve=[&](){
        for(int tt=1;tt<=tc;++tt){
            memset(vis,0,sizeof(vis));
            read(n),read(m);
            for(int i=1;i<=m;++i){
                read(r1x[i]),read(r1y[i]),read(r2x[i]),read(r2y[i]);
                r1x[i]--,r2x[i]--;
            }
            for(int i=1;i<=m;++i){
                for(c[0]=0;c[0]<=n;++c[0])
                for(c[1]=0;c[1]<=n;++c[1])
                for(c[2]=0;c[2]<=n;++c[2])
                for(c[3]=0;c[3]<=n;++c[3])
                    if(c[r1x[i]]>=r1y[i]^c[r2x[i]]>=r2y[i])
                        vis[c[0]][c[1]][c[2]][c[3]]=1;
            }
            memset(f,0,sizeof(f));
            f[0][0][0][0]=1;
            for(int col=0;col<=255;++col){
                for(int cc=0;cc<=3;++cc)
                for(c[0]=0;c[0]<=n;++c[0])
                for(c[1]=0;c[1]<=n;++c[1])
                for(c[2]=0;c[2]<=n;++c[2])
                for(c[3]=0;c[3]<=n;++c[3])
                    if(c[cc]<n){
                        int tmp=f[c[0]][c[1]][c[2]][c[3]];
                        c[cc]++;
                        f[c[0]][c[1]][c[2]][c[3]]=(f[c[0]][c[1]][c[2]][c[3]]+tmp)%mod;
                        c[cc]--;
                    }
                for(c[0]=0;c[0]<=n;++c[0])
                for(c[1]=0;c[1]<=n;++c[1])
                for(c[2]=0;c[2]<=n;++c[2])
                for(c[3]=0;c[3]<=n;++c[3])
                    if(vis[c[0]][c[1]][c[2]][c[3]]) f[c[0]][c[1]][c[2]][c[3]]=0;
            }
            printf("%05d\n",f[n][n][n][n]);
        }
    };
    // freopen("draw.in","r",stdin);
    // freopen("draw.out","w",stdout);
    //read(T);
    while(T--) solve();
    return 0;
}

T4 棋盘(knight)

题意

有一个 \(N \times M\) 的棋盘,要在上面摆上 knight,每个格子可以放至多一个knight。
knight 的攻击范围为国际象棋中马的移动范围。

所有 knight 不能互相攻击,请问总共有多少可行的摆法?答案对 1000000007 取模。

思路

状压DP

考虑压当前行,上一行,上两行三个状态。

转移还是正常转移,但是这样你会发现你寄了。

这个时候我们发现可以使用矩阵优化。

不会写。

以后考试总结都放在这里吧,现在就不补了。

标签:总结,10,ch,int,long,dp,考试,define
From: https://www.cnblogs.com/lizihan00787/p/18404773

相关文章

  • cisp-pte考试靶场及通关攻略(附靶场源码)
    cisp-pte考试靶场及通关攻略(附靶场源码)靶机安装关注后回复【pte靶场】即可,有网安交流群,要进群的小伙伴后台加群即可vm启动后改静态ipservicenetworkrestart或者重启reboot第一题【sql注入】注意这个文件路径,待会要获取答案orderby判断字段数量union判断,被过滤发......
  • 活动系统开发之采用设计模式与非设计模式的区别-后台功能总结
    1、数据库ER图2、后台功能字段题目功能字段数据列表编号题目名称选项数量状态1=启用0=禁用创建时间修改时间保存题目名称选项集选项内容是否正确答案1=正确0=错误启禁用删除素材图库功能字段数据列表编号原文件名称文件类型文件大小加密后文件名文件具体路径上传类......
  • 【内网渗透】免工具,内网和域内信息收集的40种方式总结
    前言本文主要演示了【系统信息收集】【浏览器信息收集】和【域内信息收集】,因为上一篇已经讲过了基本的信息收集方式:这篇新增了域内信息收集和浏览器信息收集,并且在上一篇文章的基础下,新增了好几种内网信息收集的方式,这里先介绍域内信息收集域内信息查看当前登录域显示和更改......
  • 伪静态注入的总结
    伪静态页面渗透在日常的测试中,经常会遇到静态页面,尤其是政府类的站点(前提经过授权),此时就会非常的棘手,在下多试验后,发现以下思路或可以帮助我们跨越这个障碍。伪静态即是网站本身是动态网页如.php、.asp、.aspx等格式动态网页有时这类动态网页还跟“?”加参数来读取数据库内不同......
  • 算法面试总结-传统图像算法
    目录1.说说相机标定?2.说说图像的边缘是什么?3.说说边缘检测的任务以及基本原理4.说说Canny边缘检测算子?5.说说除Canny外还知道什么边缘检测算子?6.说说霍夫变换步骤?7.说说仿射变换?8.说说透视变换?9.说说最小二乘法?10.说说SIFT算子以及有什么特点?11.说说SIFT特征提取与匹配算......
  • Oracle 19c OCP 认证考试 082 题库(第22题)- 2024年修正版
    【优技教育】Oracle19cOCP082题库(Q22题)-2024年修正版考试科目:1Z0-082考试题量:90通过分数:60%考试时间:150min本文为(CUUG原创)整理并解析,转发请注明出处,禁止抄袭及未经注明出处的转载。原文地址:http://www.cuug.com/index.php?s=/home/article/detail/id/3406.html第......
  • 杂题总结 Vol.2
    杂题总结Vol.2\(\def\EZ{\textcolor{#51af44}{\text{EZ}}}\EZ\)表示简单,10分钟内就能想到。\(\def\HD{\textcolor{#3173b3}{\text{HD}}}\HD\)表示中等,能独立想出\(\def\IN{\textcolor{#be2d23}{\text{IN}}}\IN\)表示困难,独立思考能想到\(50\%\)以上\(\def\AT{\textcolor......
  • Node.js 版本管理工具对比总结
    Node.js版本管理工具用于帮助开发者在不同项目中灵活切换Node.js和npm版本。常见的工具有nvm、n、nvs、fnm和Volta。以下是它们的优缺点、常用命令及对比总结。nvm(NodeVersionManager)优点:支持macOS和Linux。可以灵活地安装、切换和卸载不同版本的Node.js。......
  • 一个打工人的减脂总结
    1事情开始是因为老婆体检检查出各种问题,胰岛素抵抗,多囊卵巢综合征,体重超标等问题,我自己开始意识到我的体重需要急刹车.工作9年以来,一直是坐在电脑前办公,长时间的久坐,导致了很多职业病,肌肉劳损和用眼过度带来的流泪问题,幽冥螺旋杆菌导致的胃胀,体重也是逐年身身高,可以......
  • UDS服务总结
    手册导读 2UDS协议 2UDS介绍 2一、常见的诊断协议OBD&UDS 21.1两种常见的诊断协议:OBD&UDS 2二、相关术语介绍 32.1ServiceID 32.2诊断请求(DiagnosticRequest) 42.3正响应/负响应(Positive/NegativeResponse) 52.3.1正响应报文格式 62.3.1负响应报文格式 73.1SI......