Codeforces 585D Lizard Era: Beginning
来源:互联网 发布:linux下启动tomcat命令 编辑:程序博客网 时间:2024/05/16 08:06
题意就是
有3个人 最多25场比赛
给出每个人参加每场比赛的分数
每次比赛 你都可以选择两个人 加上那两个人的分数
最后求一个比赛完所有人分数相同的方案
如果有多个方案,求分数最大的方案
一开始看n=25
3^25太大了 根本做不完 于是就没多想 去搞别的题了
比赛完后看题目类型 meet-in-the-middle
据说白书上还有类似的题(自我反省啊!)
瞬间明白了
前一半暴力选择方案 扔map里
后一般暴力 map里查询
如果当前方案三个人的值分别是x,y,z
map可以只扔y-x,z-x的值 map的value保存a的值
如果有相同的key value取最大的
这样后一半暴力的三个人的值a,b,c
这样只需要查询 a-b,c-b的值 如果存在 那么value+a即为答案
这个代码跑了好长时间。。1900+ms 差点超时
如果直接循环方案对应的三进制数 是不是会更快一点呢?有空试试
如果不扔map 直接存的话 时间不到1s
#include<bits/stdc++.h>using namespace std;const int base=3;struct node{ long long y,z; node(long long a,long long b) { y=a; z=b; } bool operator< (const node &head) const { return head.y==y?head.z<z:head.y<y; }};map<node,int>mp;struct info{ int choice; long long x;}f[2000001];int m,n;int has=0;struct self{ int x,y,z;}s[33];long long ans;int choicex,choicey;void predfs(int dep,long long x,long long y,long long z,int choice){//for(int kk=1;kk<dep;kk++)//cout<<" ";//cout<<"dep="<<dep<<" x="<<x<<" y="<<y<<" z="<<z<<" choice="<<choice<<endl; if(dep==n+1) {//cout<<" predfs dep="<<dep-1<<" "<<x<<" "<<y<<" "<<z<<endl; y-=x; z-=x; node t=node(y,z); if(mp.find(t)!=mp.end()) { int pos=mp[t]; if(f[pos].x<x) { f[pos].x=x; f[pos].choice=choice; } } else { has++; mp[t]=has; f[has].x=x; f[has].choice=choice;//cout<<" add "<<y<<" "<<z<<" base="<<x<<" choice="<<choice<<endl; } return; } //1 2 1 3 2 3 for(int k=0;k<=2;k++) { if(k==0) { predfs(dep+1,x+s[dep].x,y+s[dep].y,z,choice*3+k); } if(k==1) { predfs(dep+1,x+s[dep].x,y,z+s[dep].z,choice*3+k); } if(k==2) { predfs(dep+1,x,y+s[dep].y,z+s[dep].z,choice*3+k); } }}void lowdfs(int dep,long long x,long long y,long long z,int choice){ if(dep==n) { y-=x; z-=x; node t=node(-y,-z); if(mp.find(t)!=mp.end()) { int pos=mp[t];//cout<<" pre="<<f[pos].x<<" low="<<x<<endl; { if(f[pos].x+x>ans) { ans=f[pos].x+x;//cout<<" ans="<<ans<<endl; choicex=f[pos].choice; choicey=choice; } } } return; } for(int k=0;k<=2;k++) { if(k==0) { lowdfs(dep-1,x+s[dep].x,y+s[dep].y,z,choice*3+k); } if(k==1) { lowdfs(dep-1,x+s[dep].x,y,z+s[dep].z,choice*3+k); } if(k==2) { lowdfs(dep-1,x,y+s[dep].y,z+s[dep].z,choice*3+k); } }}void rep(int i,int u){ if(i==1) { int t=u%3; if(t==0) printf("LM\n"); if(t==1) printf("LW\n"); if(t==2) printf("MW\n"); return; } rep(i-1,u/3); int t=u%3; if(t==0) printf("LM\n"); if(t==1) printf("LW\n"); if(t==2) printf("MW\n");}void p(int i,int u){ while(i<=m) { int t=u%3; u/=3; i++; if(t==0) printf("LM\n"); if(t==1) printf("LW\n"); if(t==2) printf("MW\n"); }}void print(int l,int r){ //cout<<ans<<endl; rep(n,l); p(n+1,r);}int main(){ ans=-1e14; scanf("%d",&m); for(int i=1;i<=m;i++) scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].z); if(m%2==0) n=m/2; else n=m/2+1; //cout<<"n="<<n<<endl; predfs(1,0,0,0,0); lowdfs(m,0,0,0,0); //cout<<ans<<endl; if(ans!=-1e14) print(choicex,choicey); else printf("Impossible\n"); return 0;}
直接存+排序+二分
980ms
#include<bits/stdc++.h>using namespace std;struct node{ long long y,z; long long x; int choice;};node g[2000001];int cmp(node head,node a){ if(head.y!=a.y) return head.y<a.y; if(head.z!=a.z) return head.z<a.z; return head.x>a.x;}struct info{ int choice; long long x;}f[2000001];int m,n;int has=0;struct self{ int x,y,z;}s[33];long long ans;int choicex,choicey;int ipow(int i,int k){ if(k==0) return 1; return i*ipow(i,k-1);}void add(long long &a,long long &b,long long &c,int k,int i){ if(k==0) { a+=s[i].x; b+=s[i].y; } if(k==1) { a+=s[i].x; c+=s[i].z; } if(k==2) { b+=s[i].y; c+=s[i].z; }}void add(int u){ int v=u; long long x=0,y=0,z=0; for(int i=n;i>=1;i--) { add(x,y,z,v%3,i); v/=3; } y-=x; z-=x; has++; g[has].x=x; g[has].y=y; g[has].z=z; g[has].choice=u;}int bs(long long y,long long z){ int l=1,r=has,mid,ret=0; while(l<=r) { mid=(l+r)>>1; if(g[mid].y>y||(g[mid].y==y && g[mid].z>=z)) { ret=mid; r=mid-1; } else l=mid+1; } if(g[ret].y==y && g[ret].z==z) return ret; else return 0;}void calc(int u){ int v=u; long long x=0,y=0,z=0; for(int i=n+1;i<=m;i++) { add(x,y,z,v%3,i); v/=3; } y-=x; z-=x; int pos=bs(-y,-z); if(pos!=0) if(g[pos].x+x>ans) { ans=g[pos].x+x; choicex=g[pos].choice; choicey=u; }}void rep(int i,int u){ if(i==1) { int t=u%3; if(t==0) printf("LM\n"); if(t==1) printf("LW\n"); if(t==2) printf("MW\n"); return; } rep(i-1,u/3); int t=u%3; if(t==0) printf("LM\n"); if(t==1) printf("LW\n"); if(t==2) printf("MW\n");}void p(int i,int u){ while(i<=m) { int t=u%3; u/=3; i++; if(t==0) printf("LM\n"); if(t==1) printf("LW\n"); if(t==2) printf("MW\n"); }}void print(int l,int r){ rep(n,l); p(n+1,r);}int main(){ ans=-1e14; scanf("%d",&m); for(int i=1;i<=m;i++) scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].z); if(m%2==0) n=m/2; else n=m/2+1; for(int i=0;i<ipow(3,n);i++) add(i); sort(g+1,g+has+1,cmp); for(int i=0;i<ipow(3,m-n);i++) calc(i); if(ans!=-1e14) print(choicex,choicey); else printf("Impossible\n"); return 0;}
0 0
- Codeforces 585D Lizard Era: Beginning
- CodeForces 585D Lizard Era: Beginning
- [Codeforces 585D] Lizard Era: Beginning (折半枚举)
- codeforces585D. Lizard Era: Beginning
- beginning
- BEGINNING
- beginning
- Beginning
- Beginning
- Beginning
- $beginning
- Beginning
- beginning
- Beginning
- beginning
- Beginning~
- beginning
- Beginning
- IIS7.5安装后ASP+access数据库连接错误的问题解决办法
- GCD 编程
- mvc 小计
- linux下C编程(一)之 hello world
- [BZOJ1106] [POI2007]立方体大作战tet
- Codeforces 585D Lizard Era: Beginning
- Leetcode Recover Binary Tree
- MyEclipse设置JAVA选中高亮显示
- pcduino里,Qt无法打开摄像头(调用了opencv)
- LeetCode40——Combination Sum II
- Java 正则表达式
- 三目运算符
- Java中HashTable和ConcurrentHashMap的区别
- 解决VMware vSphere Client与本机的鼠标无缝移出移入、剪贴板共享、共享文件夹等问题,实现虚拟机上虚拟硬件的驱动