Yahoo Programming Contest 2019 补题记录(DEF)
D - Ears
题目链接:D - Ears
大意:你在一个\(0-L\)的数轴上行走,从整数格出发,在整数格结束,可以在整数格转弯。每当你经过坐标为\(i-0.5\)的位置时(\(i\)是整数),在\(i\)的位置放置一个石子。现在给出最后的石子序列,但这个序列有可能是不合法的,定义一次操作是将第\(i\)个位置上记录的石子\(-1\)或\(+1\),求最少的操作数使得给定序列成为一个合法序列
分析:
我们记录一次行走的起点为\(S\),终点为\(T\),在这次行走中到达的最左边的点为\(L\),最右边的点为\(R\)
那么这四个点将坐标轴分成了五个部分
(1):\(0\text~L-1\),\(A_i=0\)
(2):\(L\text~S-1\),\(A_i\)为偶数(可以为0)
(3):\(S\text ~T\),\(A_i\)为奇数
(4):\(T+1\text~ R\),\(A_i\)为偶数(可以为0)
(5):\(R+1\text~ INF\),\(A_i=0\)
那么我们可以进行dp,记\(dp[i][j]\)表示在第\(i\)号格子中时属于第\(j\)个部分
每一次从\(i-1\)号格子中的\(\leq j\)的部分的最小值转移而来
注意在2,3,4部分中,如果\(A_i=0\)的话任然需要计算花费(为了到达下一个部分)
似乎可以滚动数组优化(但是懒qwq)
#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
using namespace std;
const int maxd=1000000007,N=100000;
const double pi=acos(-1.0);
typedef long long ll;
int n;
ll a[200200],dp[200200][5];
int read()
{
int x=0,f=1;char ch=getchar();
while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
return x*f;
}
int main()
{
n=read();int i;
for (i=1;i<=n;i++) a[i]=read();
for (i=1;i<=n;i++)
{
ll mind=dp[i-1][0];
dp[i][0]=dp[i-1][0]+a[i];
mind=min(mind,dp[i-1][1]);
if (a[i]) dp[i][1]=mind+(a[i]%2);else dp[i][1]=mind+2;
mind=min(mind,dp[i-1][2]);
if (a[i]) dp[i][2]=mind+((a[i]+1)%2);else dp[i][2]=mind+1;
mind=min(mind,dp[i-1][3]);
if (a[i]) dp[i][3]=mind+(a[i]%2); else dp[i][3]=mind+2;
mind=min(mind,dp[i-1][4]);
dp[i][4]=mind+a[i];
}
ll ans=min(min(dp[n][2],dp[n][3]),dp[n][4]);
printf("%lld",ans);
return 0;
}
E - Odd Subrectangles
大意:给出一个\(n\)行\(m\)列的01矩阵,你可以选定一个行集合和列集合,使得那些行数和列数均在对应集合的矩阵中的位置上的数字之和是奇数,求方案数(感觉翻译的好奇怪啊QAQ,算了意思到了(逃)
分析:
将问题转化,“和为奇数”等价于“异或和为1”
将每一行都视作一个数(\(< 2^m\)),我们考虑已经选择了任意的\(i\)行
首先如果说我们选定的这\(i\)行的异或之和为0的话,无论我们怎么选择列,选定格子的异或之和均为0
所以此时对应的方案数为0
那么如果这\(i\)行的异或和不为0的话,就说明是01交杂的
我们假设最后的异或和存在\(a\)个\(1\)和\(b\)个\(0\),那么首先就有\(a+b=m\)
同时要使所有选择的格子异或之和为奇数的话,那么我们一定会选择奇数个\(1\),而\(0\)的个数是任意的
选择\(1\)的方案数:\(C^1_a+C^3_a+\cdots+C^a_a(a\text%2=1)(或C_a^{a-1}当a\text%2=0)=2^{a-1}\)
(利用二项式定理和组合数的递推证明)
选择\(0\)的方案数:\(2^b\)
所以对于这\(i\)行而言合法的选择方案为\(2^{a-1}*2^b=2^{a+b-1}=2^{m-1}\)
我们发现,无论\(i\)的值是多少以及我们如何选取这\(i\)行,最后选取的列的方案数是一定的
由于异或和不为\(0\)的方案数=总方案数-异或和为0的方案数
所以\(ans=(2^n-行异或和为0的方案数)*2^{m-1}\)
行异或和的方案数可以用\(bitset+\)线性基完成,记最后被赋了值的线性基总数为\(x\)
则\(ans=(2^n-2^{n-r})*2^{m-1}\)(对于剩下的\(n-r\)个未被插入线性基的数,我们可以选取它和可以表示它的线性基里面的数)
直接预处理2的幂次即可
#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<bitset>
#include<map>
using namespace std;
const int maxd=998244353,N=100000;
const double pi=acos(-1.0);
typedef long long ll;
int n,m,cnt=0;
ll bin[320];
bitset<320> a[320],p[320];
int read()
{
int x=0,f=1;char ch=getchar();
while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
return x*f;
}
int main()
{
n=read();m=read();
int i,j;
bin[0]=1;
for (i=1;i<=300;i++) bin[i]=(bin[i-1]*2)%maxd;
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
{
int tmp=read();
if (tmp) a[i][j]=1;
}
}
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
{
if (a[i][j])
{
if (p[j][j]) a[i]^=p[j];
else
{
p[j]=a[i];
cnt++;
break;
}
}
}
}
ll ans=(((bin[n]-bin[n-cnt])*bin[m-1])%maxd+maxd)%maxd;
printf("%lld",ans);
return 0;
}
F - Pass
题目链接:F - Pass
题目大意:\(n\)个人站成一排,开始时每个人手上有两个球(红色或蓝色),在每一个时刻第\(i\)个人如果手上有球就随机把一个球传给第\(i-1\)个人,第\(1\)个人传给小明,小明记录下球的颜色,问最后有可能记录下的球的颜色序列有多少种?
难得F比E还简单(虽然我没有做出来)
预处理\(1-i\)个人手上有几个红球几个蓝球
记\(dp[i][j]\)表示已经记录了\(i\)个球的颜色,其中\(j\)个是红球
转移十分显然:\(dp[i][j]=dp[i-1][j]+dp[i-1][j-1]\)
注意一下当前的红球数为\(j\),蓝球数为\(i-j\)
而在枚举\(i\)的时候红球和蓝球个数均有一个上界,不能超过这个上界
同时\(j-1\geq 0\)即可
\(ans=dp[2*n][红球个数]\)
#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
using namespace std;
const int maxd=998244353,N=100000;
const double pi=acos(-1.0);
typedef long long ll;
int n,sumr[3030],sumb[3030],dp[4060][4060];
char s[3030];
int read()
{
int x=0,f=1;char ch=getchar();
while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
return x*f;
}
int main()
{
scanf("%s",s+1);
int i,j;n=strlen(s+1);
sumr[0]=0;sumb[0]=0;
for (i=1;i<=n;i++)
{
sumr[i]=sumr[i-1];sumb[i]=sumb[i-1];
if (s[i]=='0') sumr[i]+=2;
else if (s[i]=='1') {sumr[i]++;sumb[i]++;}
else if (s[i]=='2') sumb[i]+=2;
}
//for (i=1;i<=n;i++) cout << sumr[i] << " ";cout << endl;
//for (i=1;i<=n;i++) cout << sumb[i] << " ";cout << endl;
dp[0][0]=1;
for (i=1;i<=2*n;i++)
{
int nowr=sumr[min(i,n)],nowb=sumb[min(i,n)];
for (j=0;j<=i;j++)
{
if ((nowr>=j) && (nowb>=i-j))
{
dp[i][j]=dp[i-1][j];
if (j>0) dp[i][j]=(dp[i][j]+dp[i-1][j-1])%maxd;
}
}
}
printf("%lld",dp[2*n][sumr[n]]);
return 0;
}
每次做AtCoder的题都能感觉到自己的渺小
Yahoo Programming Contest 2019 补题记录(DEF)的更多相关文章
- [AtCoder] Yahoo Programming Contest 2019
[AtCoder] Yahoo Programming Contest 2019 很遗憾错过了一场 AtCoder .听说这场是涨分场呢,于是特意来补一下题. A - Anti-Adjacency ...
- 【AtCoder】Yahoo Programming Contest 2019
A - Anti-Adjacency K <= (N + 1) / 2 #include <bits/stdc++.h> #define fi first #define se se ...
- Yahoo Programming Contest 2019 自闭记
A:签到. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> ...
- Yahoo Programming Contest 2019.F.Pass(DP)
题目链接 惊了这是什么F题...怎么我都能做出来...以后atcoder的比赛也不能走神了万一有个这样的F呢(CF已有多次了= =) \(f[i][j]\)表示Takahashi现在一共有\(i\)个 ...
- Yahoo Programming Contest 2019.E.Odd Subrectangles(思路 线性基)
题目链接 \(Description\) 给定一个\(n\times m\)的\(01\)矩阵.求任意选出\(r\)行.\(c\)列(共\(2^{n+m}\)种方案),使得这\(r\)行\(c\)列的 ...
- Yahoo Programming Contest 2019.D.Ears(DP)
题目链接 菜爆了啊QAQ 记起点为\(S\),终点为\(T\),走过的最靠左的点是\(L\),最靠右的点是\(R\). 那么坐标轴被分成了五段: \(0\sim L-1\):经过\(0\)次: \(L ...
- Yahoo Programming Contest 2019 E - Odd Subrectangles
E - Odd Subrectangles 思路: 对于行方案固定的情况下,假设和为奇数的列为a个,和为偶数的列为b个,a+b = m 那么从奇数里面选奇数个,即C(a, 1) + C(a, 3) + ...
- Yahoo Programming Contest 2019 F - Pass
F - Pass 思路: dp[i][j] 表示到第 i 个球为止放了 j 个蓝球的方案数 第 i 个球来自的位置的最右边是min(i, n) 转移方程看代码 代码: #pragma GCC opti ...
- Yahoo Programming Contest 2019 D - Ears
D - Ears 思路: s:起点 t:终点 l:左端点 r:右端点 以上称为关键点 dp[i][j]表示到位置 i 为止,已经经过前 j ...
随机推荐
- Git简易的命令入门
Git 全局设置: git config --global user.name "kszsa" git config --global user.email "duyon ...
- python 获取gearbest地址库代码
import requests import json # 用来去掉多余的字符,并格式化 def geshihua(str): s = None if "/**/_get_country(& ...
- Python—生成器
列表生成式 现在有个需求,看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],要求你把列表里的每个值加1,你怎么实现? >>> a = [i+1 for i in r ...
- hdu3294(马拉车模板)
注意:string会超时 #include<bits/stdc++.h> using namespace std; #define ll long long const double PI ...
- 牛客练习赛35 C.函数的魔法
链接 [https://ac.nowcoder.com/acm/contest/32] 题意 题目描述 一位客人来到了此花亭,给了女服务员柚一个数学问题:我们有两个函数,F(X)函数可以让X变成(XX ...
- 15-分析Ajax请求并抓取今日头条街拍美图
流程框架: 抓取索引页内容:利用requests请求目标站点,得到索引网页HTML代码,返回结果. 抓取详情页内容:解析返回结果,得到详情页的链接,并进一步抓取详情页的信息. 下载图片与保存数据库:将 ...
- Podfile文件用法详解
https://www.jianshu.com/p/b8b889610b7e 2018.01.09 15:51* 字数 2343 阅读 6263评论 3喜欢 34 前言 iOS开发会经常用到cocoa ...
- Button按钮为什么无缘无故会提交form表单?
我的form表单里有好几个Button按钮,每个按钮有不同的功能,可是这些按钮居然都有提交功能,真是把我惊呆了 <button class="btn btn-info " o ...
- 在layui中使用ajax不起作用
又是一个坑,坑了我一个下午.在layui插件中使用jquery的ajax请求,一点反应都没有,不管是改成get还是post请求,后台毫无反应,前端谷歌调试也没有报半点错. js代码如下: layui. ...
- 前端开发之css
<!--页面中的组成部分通常随便打开一个网页,有文字,图片,视频,表格,音频,表单(注册信息) css 属性/尺寸/边框/背景 1.css的尺寸属性,就是大小width max-width mi ...