期望得分:80+30+70=180

实际得分:10+30+70=110

T1 水题(water)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK出了道水题。

这个水题是这样的:有两副牌,每副牌都有n张。

对于第一副牌的每张牌长和宽分别是xi和yi。对于第二副牌的每张牌长和宽分别是aj和bj。第一副牌的第i张牌能覆盖第二副牌的第j张牌当且仅当xi>=aj并且yi>=bj。(注意牌不能翻转)当然一张牌只能去覆盖最多一张牌,而不能覆盖好多张。

LYK想让两副牌的各n张一一对应叠起来。它想知道第二副牌最多有几张能被第一副牌所覆盖。

输入格式(water.in)

第一行一个数n。

接下来n行,每行两个数xi,yi。

接下来n行,每行两个数aj,bj。

输出格式(water.out)

输出一个数表示答案。

输入样例

3

2 3

5 7

6 8

4 1

2 5

3 4

输出样例

2

数据范围

对于50%的数据n<=10。

对于80%的数据n<=1000。

对于100%的数据1<=n<=100000,1<=xi,yi,aj,bj<=10^9。

对所有的牌按长从小到大排序,x相同时,第二副牌位置靠前

然后枚举所有的牌

如果是第二副牌,就把它的宽 扔到某个数据结构里

如果是第一副牌,就在这个数据结构里找<=它的宽的最大的,数据结构里把它删去,ans++

数据结构如果是数组,n^2,可得80

数据结构用权值线段树、平衡树、multiset 可得100

#include<set>
#include<cstdio>
#include<algorithm> using namespace std; #define N 100001 struct node
{
int x,y,ty;
}e[N<<]; multiset<int>s; multiset<int>::iterator it; bool cmp(node p,node q)
{
if(p.x!=q.x) return p.x<q.x;
return p.ty>q.ty;
} int main()
{
freopen("water.in","r",stdin);
freopen("water.out","w",stdout);
int n;
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d%d",&e[i].x,&e[i].y),e[i].ty=;
for(int i=;i<=n;i++) scanf("%d%d",&e[i+n].x,&e[i+n].y),e[i+n].ty=;
sort(e+,e+n*+,cmp);
n<<=; int ans=;
for(int i=;i<=n;i++)
if(e[i].ty==) s.insert(e[i].y);
else
{
if(s.empty()) continue;
it=s.upper_bound(e[i].y);
if(it==s.begin()) continue;
it--;
ans++;
s.erase(it);
}
printf("%d",ans);
}

T2 梦境(dream)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK做了一个梦。

这个梦是这样的,LYK是一个财主,有一个仆人在为LYK打工。

不幸的是,又到了月末,到了给仆人发工资的时间。但这个仆人很奇怪,它可能想要至少x块钱,并且当LYK凑不出恰好x块钱时,它不会找零钱给LYK。

LYK知道这个x一定是1~n之间的正整数。当然抠门的LYK只想付给它的仆人恰好x块钱。但LYK只有若干的金币,每个金币都价值一定数量的钱(注意任意两枚金币所代表的钱一定是不同的,且这个钱的个数一定是正整数)。LYK想带最少的金币,使得对于任意x,都能恰好拼出这么多钱。并且LYK想知道有多少携带金币的方案总数。

具体可以看样例。

输入格式(dream.in)

第一行一个数n,如题意所示。

输出格式(dream.out)

输出两个数,第一个数表示LYK至少携带的金币个数,第二数表示方案总数。

输入样例

6

输出样例

3 2

样例解释

LYK需要至少带3枚金币,有两种方案,分别是{1,2,3},{1,2,4}来恰好得到任意的1~n之间的x。

输入样例2

10

输出样例2

4 8

数据范围

对于30%的数据n<=10。

对于60%的数据n<=100。

对于100%的数据n<=1000。

最少金币数=log2(n)下取整 +1

方案数:

dp[i][j][k] 拿了i个金币,当前和为j,最大的是k的方案数

枚举 下一枚金币 h,h∈[k+1,j+1]   dp[i+1][j+h][h]+=dp[i][j][k]

#include<cmath>
#include<cstdio>
#include<algorithm> #define N 1001 int dp[][N][N]; int main()
{
freopen("dream.in","r",stdin);
freopen("dream.out","w",stdout);
int n;
scanf("%d",&n);
int x=log(n)/log()+;
dp[][][]=;
for(int i=;i<x;i++)
for(int j=;j<=n;j++)
for(int k=;k<=n;k++)
if(dp[i][j][k])
{
for(int h=k+;h<=j+;h++)
dp[i+][std::min(j+h,n)][h]+=dp[i][j][k];
}
int ans=;
for(int i=;i<=n;i++) ans+=dp[x][n][i];
printf("%d %d",x,ans);
}

T3 动态规划(dp)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK在学习dp,有一天它看到了一道关于dp的题目。

这个题目是这个样子的:一开始有n个数,一段区间的价值为这段区间相同的数的对数。我们想把这n个数切成恰好k段区间。之后这n个数的价值为这k段区间的价值和。我们想让最终这n个数的价值和尽可能少。

例如6个数1,1,2,2,3,3要切成3段,一个好方法是切成[1],[1,2],[2,3,3],这样只有第三个区间有1的价值。因此这6个数的价值为1。

LYK并不会做,丢给了你。

输入格式(dp.in)

第一行两个数n,k。

接下来一行n个数ai表示这n个数。

输出格式(dp.out)

一个数表示答案。

输入样例

10 2

1 2 1 2 1 2 1 2 1 2

输出样例

8

数据范围

对于30%的数据n<=10。

对于60%的数据n<=1000。

对于100%的数据1<=n<=100000,1<=k<=min(n,20),1<=ai<=n。

其中有30%的数据满足ai完全相同均匀分布在所有数据中。

n^2 做法:

预处理 f[i][j] 表示[l,r]的价值

dp[i][j] 表示前i个数分为j段的最小价值

状态转移:dp[i][j]=min(dp[k][j-1]+f[k+1][i])

优化:

当j固定时,k具有单调性

即 若p1由t1(绿色)转移,那么p2只能由t1及之后的t2(蓝色)转移

若p2 由t0(红色) 转移,那么可以证明p1由t0(紫色)转移更优

大概思路就是

由t2转移就是那段短的蓝色区间,由t0转移,蓝色区间延长,它延长就更容易产生价值

这样都更小的话,上面那个绿色的段区间延长也会更小

所以,如果确定了dp[mid][i] 由 dp[pos][i-1]转移

那么dp[1][i]~dp[mid-1][i]只能由 dp[1][i-1]~dp[pos][i-1]转移

dp[mid+1][i]~dp[n][i]只能由 dp[pos][i-1]~dp[n][i-1] 转移

这就可以分治下去

分治每一层都是n个点,所以时间复杂度为k*n*logn

#include<cstdio>
#include<cstring> using namespace std; typedef long long LL; #define N 100001 LL tot; int a[N]; int cnt[N],L,R; LL f[N],g[N]; void move(int l,int r)
{
while(L>l) --L,tot+=cnt[a[L]],cnt[a[L]]++;
while(L<l) cnt[a[L]]--,tot-=cnt[a[L]],L++;
while(R>r) cnt[a[R]]--,tot-=cnt[a[R]],R--;
while(R<r) ++R,tot+=cnt[a[R]],cnt[a[R]]++;
} void work(int l,int r,int opl,int opr)
{
if(opl>opr) return;
int mid=opl+opr>>;
LL mi=1e18; int pos;
for(int i=l;i<=r;i++)
if(i<mid)
{
move(i+,mid);
if(tot+f[i]<mi) mi=tot+f[i],pos=i;
}
g[mid]=mi;
work(l,pos,opl,mid-);
work(pos,r,mid+,opr);
} int main()
{
freopen("dp.in","r",stdin);
freopen("dp.out","w",stdout);
int n,k;
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
f[]=;
for(int i=;i<=n;i++) f[i]=1e18;
while(k--)
{
memset(cnt,,sizeof(cnt));
tot=; L=; R=;
work(,n-,,n);
for(int i=;i<=n;i++) f[i]=g[i],g[i]=;
}
printf("%d",f[n]);
}

70分暴力

#include<cstdio>
#include<cstring>
#include<iostream> using namespace std; #define N 1001 int n,k; int f[N][N],dp[N][N]; int a[N],sum[N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void pre()
{
for(int i=;i<n;i++)
{
sum[a[i]]++;
for(int j=i+;j<=n;j++)
{
f[i][j]=f[i][j-]+sum[a[j]];
sum[a[j]]++;
}
memset(sum,,sizeof(sum));
}
} void solve()
{
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++) dp[i][]=;
for(int i=;i<=n;i++)
{
dp[i][]=f[][i];
for(int j=;j<=min(k,i);j++)
for(int h=;h<i;h++)
dp[i][j]=min(dp[i][j],dp[h][j-]+f[h+][i]);
}
printf("%d",dp[n][k]);
} int main()
{
freopen("dp.in","r",stdin);
freopen("dp.out","w",stdout);
read(n); read(k);
if(n>)
{
printf("%I64d",1LL*n%k*(n/k)*(n/k+)/+1LL*(k-n%k)*(n/k)*(n/k-)/);
return ;
}
for(int i=;i<=n;i++) read(a[i]);
pre();
solve();
return ;
}

2017 清北济南考前刷题Day 1 afternoon的更多相关文章

  1. 2017 清北济南考前刷题Day 7 afternoon

    期望得分:100+100+30=230 实际得分:100+100+30=230 1. 三向城 题目描述 三向城是一个巨大的城市,之所以叫这个名字,是因为城市中遍布着数不尽的三岔路口.(来自取名力为0的 ...

  2. 2017 清北济南考前刷题Day 3 afternoon

    期望得分:100+40+100=240 实际得分:100+40+100=240 将每个联通块的贡献乘起来就是答案 如果一个联通块的边数>点数 ,那么无解 如果边数=点数,那么贡献是 2 如果边数 ...

  3. 2017 清北济南考前刷题Day 4 afternoon

    期望得分:30+50+30=110 实际得分:40+0+0=40 并查集合并再次写炸... 模拟更相减损术的过程 更相减损术,差一定比被减数小,当被减数=减数时,停止 对于同一个减数来说,会被减 第1 ...

  4. 2017 清北济南考前刷题Day 6 afternoon

    期望得分:100+100+30=230 实际得分: 正解: 枚举最高的位,这一位m是1但实际用了0 然后剩余的低位肯定是 正数就用1,负数用0 考场思路:数位DP #include<cstdio ...

  5. 2017 清北济南考前刷题Day 5 afternoon

    期望得分:100+100+30=230 实际得分:0+0+0=30 T1 直接模拟 #include<cstdio> #include<iostream> using name ...

  6. 2017 清北济南考前刷题Day 2 afternoon

    期望得分:100+60+70=230 实际得分:0+60+0=60 T1 可以证明如果一对括号原本就匹配,那么这对括号在最优解中一定不会被分开 所以用栈记录下没有匹配的括号 最后栈中一定是 一堆右括号 ...

  7. 2017 清北济南考前刷题Day 3 morning

    实际得分:100+0+0=100 T1 右上角是必败态,然后推下去 发现同行全是必胜态或全是必败态,不同行必胜必败交叉 列同行 所以n,m 只要有一个是偶数,先手必胜 #include<cstd ...

  8. 2017 清北济南考前刷题Day 7 morning

    期望得分:100+50+20=170 实际得分:10+50+20=80 1. 纸牌 题目描述 在桌面上放着n张纸牌,每张纸牌有两面,每面都写着一个非负整数.你的邪王真眼可以看到所有牌朝上的一面和朝下的 ...

  9. 2017 清北济南考前刷题Day 6 morning

    T1 贪心 10 元先找5元 20元 先找10+5,再找3张5 #include<cstdio> using namespace std; int m5,m10,m20; int main ...

随机推荐

  1. Java大数——快速矩阵幂

    Java大数——快速矩阵幂 今天做了一道水题,尽管是水题,但是也没做出来.最后问了一下ChenJ大佬,才慢慢的改对,生无可恋了.... 题目描述: 给a,b,c三个数字,求a的b次幂对c取余. 数据范 ...

  2. JAVA 对象序列化——Serializable

    1.序列化是干什么的?       简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存object st ...

  3. NServiceBus官方文档翻译(一)NServiceBus 概况

    NServiceBus 概况 NServiceBus 被设计用来组合面向业务的服务,它并不是用来替代诸如 WCF 一类的RPC技术. NServiceBus 不只包含通信模块,像其他成熟的SOA和DD ...

  4. 最新版ABP 动态WebAPI 日期转json带T的解决方案| ABP DateTIme Json format

    ABP动态webapi返回的json数据中,日期时间带T还有毫秒数的问题,在以往的版本中可以使用下面方法解决: 在XXXAbpWebApiModule中加上下面的代码: 很老的很老的版本有效: pub ...

  5. [2017BUAA软工]第1次个人作业

    软工第1次个人作业 一.快速看完整部教材,列出你不懂的5-10个问题,发布在你的个人博客上. 1.文中提到"积累问题领域的知识和经验(例如:对医疗或金融行业的了解)."然而我们如何 ...

  6. Alpha阶段事后诸葛分析

    一.设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件主要是解决在宿舍中购买商品的软件,不同于淘宝等软件,本软件主要是用于学生开设的店铺及宿 ...

  7. ORA-03113:通信通道的文件结尾-完美解决方案

    ORA-03113:通信通道的文件结尾-完美解决方案   oracle 文档中对这个错误这样解释: ORA-03113 错误就是说连接到数据库的网络中断了.有些错误由于频繁出现.原因复杂而被 Orac ...

  8. 我项目中使用userData的实例 UserData.js

    关于userData的介绍,请参见http://hi.baidu.com/kaisep/blog/item/1da9a3312d2da5a15edf0e87.htmlhttp://hi.baidu.c ...

  9. ZOJ3733_Skycity

    这...水题.可惜坑了无数发. 显然对于当前的半径的园,多边形的边数越多,周长越短,面积也就越小. 一开始我是用二分去做的,事实证明也是可以的,只是我坑了. 其实没必要去用二分哦,这样来考虑这问题. ...

  10. git 常用命令(含删除文件)

    git 常用命令(含删除文件) Git常用操作命令收集: 1) 远程仓库相关命令 检出仓库:$ git clone git://github.com/jquery/jquery.git 查看远程仓库: ...