1 给定一个长度为n的整数数组A,重排列数组A使得下面计算出的X最大:(n不大于15,A中的大于等于0小于等于50)

int X=0;
for(int i=0;i<n;++i) X=X+(X^A[i]);

 思路:因为抑或只用到了X的后6位,所以令f[i][j]表示已经使用的数字集合为i,得到的当前的X的后6位为j的X的最大值。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <algorithm>
#include <string>
#include <string.h>
#include <set>
using namespace std; int f[1<<15][1<<6]; class Xscoregame
{
public:
int getscore(vector <int> a)
{
const int n=(int)a.size();
memset(f,-1,sizeof(f));
f[0][0]=0;
for(int i=0;i<(1<<n);++i) for(int k=0;k<(1<<6);++k)
{
const int X=f[i][k];
if(X==-1) continue; for(int j=0;j<n;++j) if(!(i&(1<<j)))
{
int y=X+(X^a[j]);
int ni=i|(1<<j);
int nk=y&63;
if(f[ni][nk]<y)
{
f[ni][nk]=y;
}
}
}
int ans=0;
for(int i=0;i<(1<<6);++i)
{
ans=max(ans,f[(1<<n)-1][i]);
}
return ans;
}
};

  

2 给定一个只包含小写a和b的主串S和K个只包含数字0,1,2,3的模式串。可以将主串中的a变成A,b变成B。其中,a可以匹配0,1,A可以匹配2,3,b可以匹配0,2,B可以匹配1,3。对于S中一个位置p和某个模式串i,f(p,i)=1当且仅当S从p开始可以完全匹配模式串i,否则f(p,i)=0。S经过一些位置的改变使得$\sum_{p=0}^{|S|-1}\sum_{i=0}^{K-1}f(p,i)$最大。其中K不大于5,S大小不大于50。

思路:记f[i][j][k]表示到S的第i个位置,能够匹配的最长的是第j个模式串,匹配的长度是k。因为可以从二元组(j,k)中确定S从i开始前面这一段所有的位置的信息,那么下一次就可以接着找出能匹配的最长的。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <algorithm>
#include <string>
#include <string.h>
#include <set>
using namespace std; int f[55][5][55]; int check(char x,char y)
{
if(x=='a') return y=='0'||y=='1';
if(x=='A') return y=='2'||y=='3';
if(x=='b') return y=='0'||y=='2';
return y=='1'||y=='3';
} void up(int &x,int y)
{
if(y>x) x=y;
} char get(char x,char y)
{
if(x=='a')
{
if(y=='0'||y=='1') return 'a';
return 'A';
}
else
{
if(y=='0'||y=='2') return 'b';
return 'B';
}
} vector<int> get(const int id,const int L,const int spos,const string& S,const vector<string> &a,const int tag)
{
int ans0=0,ans1=0;
int nMax=0;
string tmp="";
for(int i=1;i<=L;++i)
{
tmp+=get(S[spos-(L+1-i)],a[id][i-1]);
}
tmp+=tag?S[spos]-'a'+'A':S[spos]; for(int i=0;i<(int)a.size();++i)
{
string t=a[i];
for(int j=1;j<=(int)t.size()&&j<=(int)tmp.size();++j)
{
int ok=1;
for(int x=0;x<j;++x)
{
if(!check(tmp[tmp.size()-(j-x)],t[x]))
{
ok=0; break;
}
}
if(ok)
{
if(j>nMax)
{
nMax=j;
ans1=i;
}
if(j==(int)t.size()) ++ans0;
}
}
}
return {ans0,ans1,nMax}; } class Softmatch
{
public:
int count(string S,vector<string> a)
{
const int N=(int)S.size();
const int M=(int)a.size();
memset(f,-1,sizeof(f)); int cnt0=0,cnt1=0; for(int i=0;i<M;++i)
{
if(a[i].size()==1&&check(S[0],a[i][0])) ++cnt0;
if(a[i].size()==1&&check(S[0]-'a'+'A',a[i][0])) ++cnt1;
} for(int i=0;i<M;++i)
{
if(check(S[0],a[i][0]))
{
if(a[i].size()==1) f[0][i][1]=cnt0;
else f[0][i][1]=0;
}
else if(check(S[0]-'a'+'A',a[i][0]))
{
if(a[i].size()==1) f[0][i][1]=cnt1;
else f[0][i][1]=0;
}
else f[0][i][0]=0;
}
for(int i=1;i<N;++i)
{
for(int j=0;j<M;++j) for(int k=0;k<=(int)a[j].size();++k)
{
if(f[i-1][j][k]==-1) continue;
for(int p=0;p<2;++p)
{
vector<int> t=get(j,k,i,S,a,p);
up(f[i][t[1]][t[2]],f[i-1][j][k]+t[0]);
}
}
}
int ans=0;
for(int i=0;i<M;++i) for(int j=0;j<=(int)a[i].size();++j)
{
up(ans,f[N-1][i][j]);
}
return ans;
}
};

  

3 给定一个长度为n的整数数组A(n不大于50且n为偶数)。构造出一个只包含左右圆括号的长度为n的字符串S,使得字符串满足(1)左右括号匹配;(2)对于任意两个位置i,j,若A[i]=A[j],那么必须S[i]=S[j]。问这样的字符串有多少个。

思路:将字符串分成左右两部分。总的思路是,最后左边剩余的左括号等于右边剩余的右括号数。所以对于那么只在左半部分或者右半部分的数字可以随意指定它是左括号还是右括号;对于那些在两边都出现的数字,左边的这些数字出现为左括号的在右半部分必须为右括号。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <algorithm>
#include <string>
#include <string.h>
#include <set>
using namespace std; int Mask[1<<25]; class ColorfulParentheses
{
vector<int> c;
int n;
int mp[55],nId;
vector<int> S[2][26]; void dfs(int dep,int num,int tag,long long open,long long close)
{
if(dep==n)
{
S[tag][num].push_back(open&((1ll<<nId)-1));
return;
}
if(tag)
{
int t=mp[c[dep]];
if(!(close&(1ll<<t))) dfs(dep+1,num+1,tag,open|1ll<<t,close);
if(num&&!(open&(1ll<<t))) dfs(dep+1,num-1,tag,open,close|(1ll<<t));
}
else
{
int t=mp[c[n*2-1-dep]];
if(!(open&(1ll<<t))) dfs(dep+1,num+1,tag,open,close|1ll<<t);
if(num&&!(close&(1ll<<t))) dfs(dep+1,num-1,tag,open|1ll<<t,close);
}
} public:
long long count(vector<int> color)
{
c=color;
n=(int)c.size()>>1;
nId=0;
int L[55],R[55];
memset(L,0,sizeof(L));
memset(R,0,sizeof(R));
for(int i=0;i<n;++i) ++L[c[i]],++R[c[i+n]];
for(int i=0;i<n;++i)
{
if(L[c[i]]&&R[c[i]]) mp[c[i]]=nId++;
}
for(int i=0,t0=0,t1=0;i<n;++i)
{
if(L[c[i]]&&0==R[c[i]]) mp[c[i]]=nId+(t0++);
if(0==L[c[i+n]]&&R[c[i+n]]) mp[c[i+n]]=nId+(t1++);
}
dfs(0,0,0,0,0);
dfs(0,0,1,0,0);
long long ans=0;
for(int i=0;i<=n;++i)
{
for(int j=0;j<(int)S[0][i].size();++j) ++Mask[S[0][i][j]];
for(int j=0;j<(int)S[1][i].size();++j) ans+=Mask[S[1][i][j]];
for(int j=0;j<(int)S[0][i].size();++j) --Mask[S[0][i][j]];
}
return ans;
}
};

  

topcoder srm 709 div1的更多相关文章

  1. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

  2. Topcoder Srm 726 Div1 Hard

    Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...

  3. topcoder srm 714 div1

    problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...

  4. topcoder srm 738 div1 FindThePerfectTriangle(枚举)

    Problem Statement      You are given the ints perimeter and area. Your task is to find a triangle wi ...

  5. Topcoder SRM 602 div1题解

    打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...

  6. Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串

    Problem Statement      The Happy Letter game is played as follows: At the beginning, several players ...

  7. Topcoder SRM 584 DIV1 600

    思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...

  8. TopCoder SRM 605 DIV1

    604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...

  9. topcoder srm 575 div1

    problem1 link 如果$k$是先手必胜那么$f(k)=1$否则$f(k)=0$ 通过对前面小的数字的计算可以发现:(1)$f(2k+1)=0$,(2)$f(2^{2k+1})=0$,(3)其 ...

随机推荐

  1. jq文件上传及下载

    一.使用jquery.form.js上传文件 jquery.form.js获取地址:https://pan.baidu.com/s/1nSdfkCt25Rc5cHMFJRVcUQ 提取码: sbmt ...

  2. 学习笔记<3>View接触

    一.View基本概念 1.界面上显示所有的控件都是用对象表示的,即有类,这些类都是View的子类. 2.View的种类 二.在Activity当中获取代表View的对象 1.根据ID可以用方法获取到对 ...

  3. 7.线程id,优先级讲解

    1.线程id可以通过Thread对象的getId()方法得到,在线程出了问题,为什么CPU占用这么高的时候,查的时候我们可以在堆栈信息中找到对应线程,然后干掉该线程就好! 2.而线程对象的getNam ...

  4. Lua 可变参数之arg与select

    function TestFunc(...) local arg = { ... } --Lua .2以后不再支持默认arg参数,{}与...之间要有空格 print("输入的参数个数:&q ...

  5. Java集合-----Map详解

          Map与Collection并列存在.用于保存具有映射关系的数据:Key-Value      Map 中的 key 和  value 都可以是任何引用类型的数据      Map 中的 ...

  6. JDBC (29)

    1.JDBC:就是一套API,由sun公司定义类或者定义的接口.(全称 java database connectivity:是Java访问数据库的标准规范),Java提供访问数据库规范称为JDBC, ...

  7. 20165215 实验三 敏捷开发与XP实践

    20165215 实验三 敏捷开发与XP实践 一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:张家佳 学号:20165215 指导教师:娄嘉鹏 实验日期:2018年4月28日 实验时 ...

  8. Unable to open socket file: target process not responding or HotSpot VM not loaded

    Unable to open socket file: target process not responding or HotSpot VM not loaded The -F option can ...

  9. Chrome插件消息传递实例

    首先吐槽"360极速浏览器应用开发平台"的开发文档,在消息传递(http://open.chrome.360.cn/extension_dev/messaging.html)一节中 ...

  10. Ubuntu 为 root 帐号开启 SSH 登录

    1. 修改 root 密码sudo passwd root 2. 以其他账户登录,通过 sudo nano 修改 /etc/ssh/sshd_config :xxx@ubuntu:~$ su - ro ...