【AtCoder】 ARC 096
link
C-Half and Half
题意:三种pizza,可以花\(A\)价钱买一个A-pizza,花\(B\)价钱买一个B-pizza,花\(C*2\)价钱买A-pizza和B-pizza各一个,需要\(x\)个A-pizza和\(y\)个B-pizza,最小化代价
枚举买多少个AB-pizza即可
#include<bits/stdc++.h>
#define ll long long
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
#define dbg3(x) cerr<<#x<<"\n"
using namespace std;
#define reg register
inline 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<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
ll ans,A,B,C,X,Y;
ll val(ll i){return i*2ll*C+max(X-i,0ll)*A+max(Y-i,0ll)*B;}
int main()
{
A=read(),B=read(),C=read(),
X=read(),Y=read();
reg int i;
ans=val(0);
for(i=1;i<=X||i<=Y;++i)
ans=min(ans,val(i));
return 0*printf("%lld\n",ans);
}
D-Static Sushi
题意:环形吧台,从指定点开始,移动需要耗体力,吃寿司可涨体力,求最大收益
分别枚举顺时针走,逆时针走,先顺后逆,先逆后顺
#include<bits/stdc++.h>
#define ll long long
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
#define dbg3(x) cerr<<#x<<"\n"
using namespace std;
#define reg register
inline ll read()
{
ll 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<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int MN=1e5+5;
ll N,C,X[MN],W[MN];
ll p1,p2,s1,s2,p1m[MN],p2m[MN],s1m[MN],s2m[MN];
int main()
{
N=read(),C=read();
reg int i;
for(i=1;i<=N;++i) X[i]=read(),W[i]=read();
X[N+1]=C;
for(i=1;i<=N;++i)
{
p1+=W[i]+X[i-1]-X[i];
p2=p1-X[i];
p1m[i]=max(p1m[i-1],p1);
p2m[i]=max(p2m[i-1],p2);
}
for(i=N;i;--i)
{
s1+=W[i]-X[i+1]+X[i];
s2=s1-C+X[i];
s1m[i]=max(s1,s1m[i+1]);
s2m[i]=max(s2,s2m[i+1]);
}
ll ans=0;
for(i=1;i<=N;++i)
ans=max(p2m[i]+s1m[i+1],ans),
ans=max(p1m[i],ans);
for(i=1;i<=N;++i)
ans=max(s2m[i]+p1m[i-1],ans),
ans=max(s1m[i],ans);
return 0*printf("%lld\n",ans);
}
E-Everything on it
题意:有\(n\)个元素,一种合法的方案为任意多个集合,每个集合互不相同,\(n\)个元素的出现次数不少于\(2\)次,求方案数,对\(M\)(是质数)取模,\(n\le 3000\)
容斥。
\]
\(W(i)\)表示表示至少有\(i\)个元素出现小于\(2\)次的方案数
\]
\(f(i,j)\)表示球标号,盒子不标号,球可以不放,盒子非空的方案数,递推可得
#include<bits/stdc++.h>
#define ll long long
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
#define dbg3(x) cerr<<#x<<"\n"
using namespace std;
#define reg register
inline 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<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
int N,M;
const int MN=3005;
int fac[MN],inv[MN],pw[9000005];
int Mul(int x,int y){return (1ll*x*y)%M;}
int Add(int x,int y){return (x+y)%M;}
int C(int x,int y){return Mul(fac[x],Mul(inv[y],inv[x-y]));}
int f[MN][MN],g[MN],ans;
int main()
{
N=read();M=read();
reg int i,j;
for(pw[0]=i=1;i<=N*N;++i) pw[i]=Mul(2,pw[i-1]);
for(fac[0]=i=1;i<=N;++i)fac[i]=Mul(fac[i-1],i);
for(inv[0]=inv[1]=1,i=2;i<=N;++i)inv[i]=Mul(inv[M%i],(M-M/i));
for(i=2;i<=N;++i)inv[i]=Mul(inv[i-1],inv[i]);
f[0][0]=1;
for(i=1;i<=N;++i)for(f[i][0]=1,j=1;j<=i;++j)
f[i][j]=Add(f[i-1][j],Add(f[i-1][j-1],Mul(f[i-1][j],j)));
reg int tmp=2;
for(i=N;~i;--i,tmp=Mul(tmp,tmp))for(j=0;j<=i;++j)
g[i]=Add(g[i],Mul(f[i][j],Mul(tmp,pw[(N-i)*j])));
for(i=0;i<=N;++i)
ans=Add(ans,Mul((i&1?M-1:1),Mul(C(N,i),g[i])));
return 0*printf("%d\n",ans);
}
F-Sweet Alchemy
题意:有棵树,每个点都有代价,要求从上面取点,单个点可取多次,孩子取的次数大于等于父亲的次数且小于等于父亲次数\(+D\),代价和不超过\(X\),求最多取多少次。
很容易转化题面为:
每个点的代价为子树代价和,价值为子树大小,除\(1\)点可取inf次外,其它都只能选最多\(D\)个
除了\(n\),以及价值很小(\(\le 50\)),其它都很大
考虑贪心做法:每次取性价比高的,取到不能取为止
但是这么做是有问题的
假设有一种做法,性价比高的还剩下50个,而性价比低已经选了50个,那么可以将他们互换,数量为对方的价值大小,这样贡献不变,体积减小
因为如果性价比高的数有\(>50\)个没选,那么性价比低的数选的数量一定\(<50\),所以将物品分为两个部分,第一个部分每个物品为50个(或者少于50个),\(f[i],i\le N^3\),表示达到这样价值需要的最少体积,第二个部分为剩下部分,贪心选择性价比高的就可以了
最后枚举第一个部分贡献的价值,求第二个部分的最大价值即可
发现答案一定再枚举的方案中
#include<bits/stdc++.h>
#define ll long long
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
#define dbg3(x) cerr<<#x<<"\n"
using namespace std;
#define reg register
inline ll read()
{
ll 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<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int MN=51;
ll N,X,D,v[MN],p[MN],z[MN],id[MN],nm[MN];
vector<int>s[MN];
void dfs(int x)
{
reg int i;p[x]=1;
for(i=s[x].size()-1;~i;--i)
dfs(s[x][i]),v[x]+=v[s[x][i]],p[x]+=p[s[x][i]];
}
ll f[MN*MN*MN];
bool cmp(const int&x,const int&y){return p[x]*v[y]>p[y]*v[x];}
signed main()
{
N=read(),X=read(),D=read();
reg ll i,j,k;ll lim=0;
for(v[1]=read(),i=2;i<=N;++i)
v[i]=read(),s[read()].push_back(i),z[i]=min(D,N);
dfs(1);z[1]=N;
for(i=1;i<=N;++i)lim+=z[i]*p[i];
for(i=1;i<=lim+1;++i)f[i]=1e18;
for(i=1;i<=N;++i)for(j=lim;j;--j)
{
ll r=min(z[i],j/p[i]);
for(k=1;k<=r;++k)f[j]=min(f[j],f[j-p[i]*k]+v[i]*k);
f[j]=min(f[j],f[j+1]);
}
for(z[1]=1e18,i=2;i<=N;++i)z[i]=D-z[i];
for(i=1;i<=N;++i)id[i]=i;
std::sort(id+1,id+N+1,cmp);
ll ans=0;
for(j=X,i=1;i<=N;++i)
{
nm[i]=min(z[id[i]],j/v[id[i]]);
ans+=p[id[i]]*nm[i];
j-=v[id[i]]*nm[i];
}
ll tmp=ans;
for(j=X-j,k=i,i=1;i<=lim;++i)
{
if(f[i]>X)break;
ll most=X-f[i];
while(j>most)
{
while(!nm[k])--k;
ll n=(j-most+v[id[k]]-1)/v[id[k]];
n=min((ll)n,nm[k]);nm[k]-=n;
j-=v[id[k]]*n;tmp-=p[id[k]]*n;
}
ans=max(ans,tmp+i);
}
printf("%lld\n",ans);
return 0;
}
Blog来自PaperCloud,未经允许,请勿转载,TKS!
【AtCoder】 ARC 096的更多相关文章
- 【AtCoder】ARC 081 E - Don't Be a Subsequence
[题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...
- 【Atcoder】ARC 080 E - Young Maids
[算法]数学+堆 [题意]给定n个数的排列,每次操作可以取两个数按序排在新序列的头部,求最小字典序. [题解] 转化为每次找字典序最小的两个数按序排在尾部,则p1和p2的每次选择都必须满足:p1在当前 ...
- 【Atcoder】ARC 080 F - Prime Flip
[算法]数论,二分图最大匹配 [题意]有无限张牌,给定n张面朝上的牌的坐标(N<=100),其它牌面朝下,每次操作可以选定一个>=3的素数p,并翻转连续p张牌,求最少操作次数使所有牌向下. ...
- 【AtCoder】 ARC 097
link C-K-th Substring 题意:找出已知串中第\(k\)大的子串,子串相同的不算 \(k\)好小啊,要怎么做啊 不是[Tjoi2015]弦论吗 算了,直接SAM吧 #include& ...
- 【AtCoder】 ARC 098
link C-Attention 题意:一个字符队列,每个位置是\(W\)或\(E\),计算最小的修改数量,使得存在一个位置,它之前的都是\(E\),之后的都是\(F\) #include<bi ...
- 【AtCoder】 ARC 099
link C-Minimization 枚举覆盖\(1\)的区间,两边的次数直接算 #include<bits/stdc++.h> #define ll long long #define ...
- 【AtCoder】 ARC 100
link C-Linear Approximation 给出\(N\)个数\(A_1,A_2,...,A_N\) ,求一个数\(d\),最小化\(\sum_{i=1}^N|A_i-(d+i)|\) 把 ...
- 【AtCoder】 ARC 101
link 搬来了曾经的题解 C-Candles 题意:数轴上有一些点,从原点开始移动到达这些点中的任意\(K\)个所需要的最短总路程 \(K\)个点必然是一个区间,枚举最左边的就行了 #include ...
- 【AtCoder】 ARC 102
link C-Triangular Relationship 发现要么全部是\(K\)的倍数,要么全部是模\(K\)余\(K/2,(K=2n)\) #include<bits/stdc++.h& ...
随机推荐
- (原创)理解主机设备(PLC,PC机)之间的以太网通信
主机设备:PC机,PLC 网络设备:家用路由器 局域网包括了有线局域网和无线局域网(WIFI).怎么去使用2者? 网络设备的职责最终目的为了帮助2台主机的数据传输.路由器,交换机范围不同,目的相同.在 ...
- Redis常用配置和命令总结
Redis(全称:Remote Dictionary Server 远程字典服务)是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言 ...
- 【转载】C#中ArrayList集合类使用RemoveAt方法移除指定索引的元素
ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,在Array ...
- 数据库-如何创建SQL Server身份验证用户
1.简介 默认安装SQL Server数据库后,SQL Server通过工具SQL Server Management Studio(SSMS)采用“Windows身份验证”方式登录,需要设置相应用户 ...
- 英语bitellos钻石bitellos单词
大颗粒的钻石叫做bitellos,四大钻石指的就是“摄政王”.“南非之星”.“蓝色希望”和“光明之山”四颗钻石.经过琢磨的钻石光彩夺目.灿烂无比,历来被誉为“宝石之王”,科研领域里大颗粒的钻石叫做bi ...
- Cheat Engine 模糊数值
打开游戏 玩到换枪为止 换枪 发现子弹数量是有限的200 扫描200 这是初次扫描 开两枪 剩余子弹数量194 再次扫描194 得到地址 尝试得到的这两个地址,经验证,第二个是我们想要的地址 重新开始 ...
- linux虚拟机网络配置
环境:虚拟机-最小化安装 centos7 主机:win10 参考配置文件: TYPE=EthernetPROXY_METHOD=noneBROWSER_ONLY=noBOOTPROTO=stat ...
- 泛微e-cology OA系统某接口存在数据库配置信息泄露漏洞复现
1.简介(开场废话) 攻击者可通过存在漏洞的页面直接获取到数据库配置信息.如果攻击者可直接访问数据库,则可直接获取用户数据,甚至可以直接控制数据库服务器. 2.影响范围 漏洞涉及范围包括不限于8.0. ...
- Tensorflow简单实践系列(二):张量
在上一节中,我们安装 TensorFlow 并运行了最简单的应用,这节我们熟悉 TensorFlow 中的张量. 张量是 TensorFlow 的核心数据类型.数学里面也有张量的概念,但是 Tenso ...
- Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code
Educational Codeforces Round 69 (Rated for Div. 2) E. Culture Code 题目链接 题意: 给出\(n\)个俄罗斯套娃,每个套娃都有一个\( ...