BestCoder Round #58
来源:互联网 发布:淘宝玻璃茶具套装 编辑:程序博客网 时间:2024/05/16 05:02
hdu5494 Problem 0. Card Game
怎么选择m个数都能赢,最小的m个数之和大于对方的最大的m个数之和就好了。
#include <cstdio>#include <iostream>#include <cmath>#include <cstring>#include <algorithm>#include <stdlib.h>#include <map>#include <vector>#define rep(i,n) for(i=0;i<n;i++)#define cle(x) memset(x,0,sizeof(x))#define ll long longconst int maxn=1000+5;using namespace std;int main(){#ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout);#endif int T; cin>>T; int a[maxn],b[maxn],n,m; while(T--){ cin>>n>>m; int i;rep(i,n)cin>>a[i]; rep(i,n)cin>>b[i]; int sum[maxn]; sort(a,a+n);sort(b,b+n); int ip=0;rep(i,n){ if(i==0)sum[i]=a[i]; else sum[i]=sum[i-1]+a[i]; } int sumb[maxn]; for(i=n-1;i>=0;i--){ if(i==n-1)sumb[ip++]=b[i]; else sumb[ip++]=sumb[ip-1]+b[i]; } if(sum[m-1]>sumb[m-1])cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0;}
hdu 5495 Problem 1. LCS
题意
子序列,按照相同的排列顺序,重新排列,是相同子序列最长。
解法
每个环之间是独立的,在独立的一个环上的选择,最优情况要舍掉一个数字,比如1->2 2->3 3->4 4->1 序列(1,2,3,4)和序列(2,3,4,1)就要舍掉1
#include <cstdio>#include <iostream>#include <cmath>#include <cstring>#include <algorithm>#include <stdlib.h>#include <map>#include <vector>#define rep(i,n) for(i=0;i<n;i++)#define cle(x) memset(x,0,sizeof(x))#define ll long longconst int maxn=100000+5;using namespace std;int a[maxn],b[maxn],u[maxn];int v[maxn];int main(){#ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout);#endif int T; cin>>T; int n; while(T--) { cle(v); cin>>n; int i; rep(i,n) { scanf("%d",&a[i]); } rep(i,n) { scanf("%d",&b[i]); } rep(i,n) { u[a[i]]=b[i]; } int ans=0; rep(i,n) { if(a[i]==b[i]) { ans++; v[a[i]]=1; continue; } if(v[a[i]]==0) { v[a[i]]=1; int temp=1; int now=u[a[i]]; while(true) { if(v[now]) { break; } else { v[now]=1; temp++; now=u[now]; } } ans+=temp; ans--; } } cout<<ans<<endl; } return 0;}
hdu 5496 Problem 2. Beauty of Sequence
题意:
所有子序列和之和,子序列中连续相邻相同元素只算一次。
解法:
官方解法:一个数的如果是几个连续相同数的第一个,他的贡献计算。
总的方案数=之前的方案数*之后的方案数
之前的方案数=所有方案数-以和他相同数作为倒数第二个的方案数 用map统计就好了
#include <cstdio>#include <iostream>#include <cmath>#include <cstring>#include <algorithm>#include <stdlib.h>#include <map>#include <vector>#define rep(i,n) for(i=0;i<n;i++)#define cle(x) memset(x,0,sizeof(x))#define ll long longconst int maxn=100000+5;const int mod=1e9+7;using namespace std;ll a[maxn];ll b[maxn];int n;void init(){ b[0]=0; for(int i=1;i<maxn;i++){ b[i]=(b[i-1]*2+1)%mod; } }map<ll,ll>mp;void doit(){ mp.clear();ll sum=0; for(int i=1;i<=n;i++) { ll be=(b[i-1]+1-mp[a[i]]+mod)%mod;//之前的 ll en=b[n-i]+1;//之后的 sum=((sum+((a[i]*((be*en)%mod))%mod))%mod); mp[a[i]]=(mp[a[i]]+b[i-1]+1)%mod; } cout<<sum<<endl;}int main(){#ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout);#endif int T;cin>>T;init(); while(T--) { cin>>n; for(int i=1;i<=n;i++){ scanf("%I64d",&a[i]); } doit(); } return 0;}
hdu 5497 Problem 3. Inversion
题意:
一个序列 ,可以删除一个长度为m的连续子序列. 问如何删除才能使逆序对最少。
解法:
删掉的应该是构成逆序对最多那些
向前连线(比他大的)
向后两线(比他小的)
选择的区间可能重复计算了。连接的两端都在区间内。
删掉的数目=所有的连线(每个数向前连线+向后连线)-区间内构成的逆序对个数(一个树状数组可维护,能想到怎么维护就可以解决了)
备注:
由于我自己写的思路比较露骨,所以有时提交超时有时候AC,可以加一些输入输出挂之类的~
#include <cstdio>#include <iostream>#include <cmath>#include <cstring>#include <algorithm>#include <stdlib.h>#include <map>#include <vector>#define rep(i,n) for(i=0;i<n;i++)#define cle(x) memset(x,0,sizeof(x))#define ll long longconst int maxn=100000+5;using namespace std;ll a[maxn],rea[maxn];ll b[maxn],qu[maxn];ll sum[maxn];int lowbit(int x){ return x&(-x);}ll getsum(int x){ ll re=0; for(int i=x-1;i>0;i-=lowbit(i))re+=sum[i]; return re;}void update(int x,ll y){ for(int i=x;i<maxn;i+=lowbit(i))sum[i]+=y;}int main(){#ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout);#endif int T; cin>>T; while(T--) { int n,m; scanf("%d%d",&n,&m); int i; rep(i,n){ scanf("%I64d",&a[i]);rea[i]=n-a[i]+1;} cle(sum);ll cot=0; for(i=n-1;i>=0;i--){ b[i]=getsum(a[i]);cot+=b[i]; update(a[i],1); } if(m==0||cot==0){ printf("%I64d\n",cot); continue; } cle(sum); rep(i,n){ b[i]+=getsum(rea[i]);//每个位置构成逆序对,向前向后之和 update(rea[i],1); } cle(sum);qu[0]=0; for(i=0;i<m;i++){ qu[0]+=getsum(rea[i]);//维护第一个m个连续的数的逆序对个数 update(rea[i],1); }int ip=1; for(i=1;i<=n-m;i++){ qu[ip]=qu[ip-1]-(getsum(n+1)-getsum(rea[i-1]+1));//去掉第一个数的构成个数 update(rea[i-1],-1); qu[ip]+=getsum(rea[i+m-1]);//加上最新数构成个数 update(rea[i+m-1],1); ip++; } ll maxans=0;ll now=0; for(i=0;i<m;i++)now+=b[i]; for(i=0;i<=n-m;i++){ maxans=max(maxans,now-qu[i]); now-=b[i];now+=b[i+m]; } printf("%I64d\n",cot-maxans); } return 0;}
hdu 5498 Problem 4. Tree
现如今能力不足~
0 0
- BestCoder Round #58
- BestCoder Round #58 LCS
- BestCoder Round #58 (div.2)
- BestCoder Round #58(Inversion-线段树)
- BestCoder Round #3 BestCoder Sequence
- bestcoder round #1
- BestCoder round #1
- BestCoder Round #1
- 【索引】BestCoder Round #2
- BestCoder Round #2
- 【索引】BestCoder Round #3
- BestCoder Round #3
- BestCoder Round #3 小记
- BestCoder Round #4 题解
- BestCoder Round #6
- BestCoder Round #8
- Bestcoder Round #9
- BestCoder Round #9
- swapPairs
- TrueType和Bitmap字体的区别
- 第六周--后缀表达式
- Guava 学习笔记 02
- Strings and Regular Expressions(homework for 02)
- BestCoder Round #58
- C++中引用(&)的用法和应用实例
- 文章标题
- 4.19**
- java——练习题4.16
- [hiho]#1069 : 最近公共祖先·三 线段树|树转数组
- linux中cat、more、less、tail、head命令的区别
- java记——关于溢出
- POJ 1985 Cow Marathon(两次BFS求树的直径(最长路))