一些sb题(day1下)
来源:互联网 发布:做视频短片的软件 编辑:程序博客网 时间:2024/06/06 17:59
t1
有两副牌,每副牌都有n张。
对于第一副牌的每张牌长和宽分别是xi和yi。对于第二副牌的每张牌长和宽分别是aj和bj。第一副牌的第i张牌能覆盖第二副牌的第j张牌当且仅当xi>=aj并且yi>=bj。(注意牌不能翻转)当然一张牌只能去覆盖最多一张牌,而不能覆盖好多张。
LYK想让两副牌的各n张一一对应叠起来。它想知道第二副牌最多有几张能被第一副牌所覆盖。
这个题用贪心
对两副牌各自进行排序,然后贪心
枚举a,找a能覆盖的所有牌,去盖最接近的,为什么这样行呢
你的x是从小到大的,后面的牌只可能盖不到y,x一定能盖到
我是对y贪的,不对,因为不是所有牌都要盖。。
然后某些东西用平衡树维护。。
#include <stdio.h>#include <string.h>#include <algorithm>#include <iostream>#include <set>using namespace std;int n;multiset <int> s;struct node {int x,y;} a[100005],b[100005];int cmp(node i,node j) {return i.x<j.x;}int main(){ freopen("water.in","r",stdin); freopen("water.out","w",stdout); int T; T=1; while(T--) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d%d",&a[i].x,&a[i].y); for(int i=0;i<n;i++) scanf("%d%d",&b[i].x,&b[i].y); sort(a,a+n,cmp); sort(b,b+n,cmp); s.clear(); int k=0,ans=0; for(int i=0;i<n;i++) { while(a[i].x>=b[k].x&&k<n) { s.insert(b[k].y); k++; } if(s.empty())continue; multiset<int>::iterator it=s.upper_bound(a[i].y); if (it==s.begin()) continue; it--; ans++; s.erase(it); } printf("%d\n",ans); } return 0;}
t2
题意
求最少有多少数能组成1~n的所有数
这个最少的就是用二进制组的,1 2 4 8一定能
方案就用dp
dp[i][j][k] 当前有i个金币,金币和是j,下一个金币。
第一层可以滚动掉
#include<cstdio>#include<cstring>#include<iostream>#include<cmath>int opt,n,ans,dp[2][1100][1100];int main(){ scanf("%d",&n); int s=log(n)/log(2)+1; printf("%d ",s); dp[0][1][1]=1; for(int i=1;i<s;i++) { memset(dp[opt^1],0,sizeof dp[opt^1]); for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) if(dp[opt][j][k]) for(int q=k+1;q<=j+1;q++) dp[opt^1][std::min(n,j+q)][q]+=dp[opt][j][k]; opt^=1; } for(int i=1;i<=n;i++) ans+=dp[opt][n][i]; printf("%d",ans);}
t3
60
简单的动规。。
#include<cstdio>#include<iostream>#include<cstring>using namespace std;int dp[1100][21][1100],n,k,a[110000],s[1100][1100],ans=199999999;int main() { freopen("dp.in","r",stdin); freopen("dp.out","w",stdout); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); for(int j=1;j<=n;j++) s[i][j]=s[i-1][j]; s[i][a[i]]++; } memset(dp,127,sizeof dp); dp[1][1][1]=0; for(int i=1;i<=n;i++) for(int j=1;j<=k;j++){ if(j<k){ for(int q=j-1;q<i;q++) dp[i][j][q]=min(dp[i-1][j][q]+s[i-1][a[i]]-s[q-1][a[i]],dp[i][j][q]); for(int q=j-1;q<i;q++) dp[i][j+1][i]=min(dp[i-1][j][q],dp[i][j+1][i]); } else { for(int q=j-1;q<i;q++) dp[i][j][q]=min(dp[i-1][j][q]+s[i-1][a[i]]-s[q-1][a[i]],dp[i][j][q]); } } for(int i=k;i<n;i++) ans=min(ans,dp[n][k][i]); printf("%d ",ans);}
正解`不会#include<iostream>#include<cstdio>using namespace std;const int N=100010;typedef long long LL;int c[N],a[N];LL f[N],g[N];int p,q,n,k;LL tot;void move(int l,int r) // [p,q]之前的区间{ while (l<p) p--,tot+=c[a[p]],c[a[p]]++; while (r>q) q++,tot+=c[a[q]],c[a[q]]++; while (p<l) c[a[p]]--,tot-=c[a[p]],p++; while (r<q) c[a[q]]--,tot-=c[a[q]],q--;}void work(int l,int r,int fl,int fr)//需要求dp[fl] ~ dp[fr] 最优解一定从l~r中的某一个转移过来{ if (fl>fr) return; int mid=(fl+fr)>>1,mi; LL mx=1LL<<60; for (int i=l;i<=r;i++) if (i<mid) { move(i+1,mid); -> tot=sum(i+1,mid); if (f[i]+tot<mx) mx=f[i]+tot,mi=i; } g[mid]=mx; work(l,mi,fl,mid-1); work(mi,r,mid+1,fr);}int main(){ freopen("dp.in","r",stdin); freopen("dp.out","w",stdout); scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) scanf("%d",&a[i]); f[0]=0; for (int i=1;i<=n;i++) f[i]=1LL<<60; while (k--) { p=1,q=0,tot=0; for (int i=1;i<=n;i++) c[i]=0; work(0,n-1,1,n); for (int i=0;i<=n;i++) f[i]=g[i],g[i]=0; } cout<<f[n]; return 0;}`
阅读全文
1 0
- 一些sb题(day1下)
- BZOJ:4300 绝世好(sb)题
- 一道sb题
- sb
- SB
- sb
- SB
- 每日一题(day1)
- SB、XIB的一些小技巧
- 一些现在才知道的SB东西
- 八数码sb(曾经的神题)题
- 英语SB(small baby)
- BZOJ_P4300 绝世好(sb)题(动态规划)
- BZOJ_P2761 [JLOI2011]不重复数字(sb题)
- SB tree (Size Balanced Tree)
- day1:关于线程的一些概念
- python算法题day1
- Ant学习(Day1)
- ListView实现下拉刷新(一)
- 应用Public API配置XenMobile Server
- 完整的支付体系
- 成员变量和类变量的区别?
- mybatis 配置错误 XML document structures must start and end within the same entity
- 一些sb题(day1下)
- S32K144 EVB之UART
- Reverse Integer算法研究
- java 基础--问题收集
- C++中ANSI、Unicode16、UTF-8字符串之间的互转
- CSS 浮动实例。为了兼容,浮动元素放在所在行的最前面
- c++原子操作内存序
- 刷题#R3
- 必测的支付漏洞(三)服务器未返回支付结果前进行干预