1、给定一个$n$个顶点$n$个边的图,边是$(i,a_{i})$,顶点编号$[0,n-1]$。增加一个顶点$n$,现在选出一个顶点集$M$,对于任意的在$M$中 的顶点$x$,去掉边$(x,a_{x})$,增加边$(x,n)$。最后使得顶点0和1相连。有多少种$M$?

思路:设从0开始可以遍历的顶点集合为$A$,从1可以遍历的顶点集合为$B$,$C=A\bigcap B$。令$A^{'}=A-C,B^{'}=B-C$。那么有下面的情况:

(1)在$C$中选择一些点(至少一个),从$A^{'},B^{'}$中任意选点;

(2)在$C$中不选择点,从$A^{'},B^{'}$中任意选点(不能为空);

(3)假设$C$不为空,那么可以不从$A^{'},B^{'},C$中选择。

对于不在$A^{'},B^{'},C$中的点都是随便选。

#include <stdio.h>
#include <string>
#include <stack>
#include <vector>
#include <string.h>
#include <algorithm>
#include <assert.h>
using namespace std; const int N=55; #define B(x) (1ll<<(x)) class Sunnygraphs {
public:
long long count(vector<int> a)
{
int n=(int)a.size();
vector<int> mask(n);
for(int i=0;mask[i]<1;i=a[i]) mask[i]|=1;
for(int i=1;mask[i]<2;i=a[i]) mask[i]|=2;
int c[4]={0,0,0,0};
for(int i=0;i<n;++i) ++c[mask[i]]; long long ans=0;
ans+=(B(c[3])-1)*B(c[1])*B(c[2]);
ans+=(B(c[1])-1)*(B(c[2])-1);
if(c[3]) ++ans;
ans<<=c[0];
return ans;
}
};

2、给定$n$组数字$(a_{i},b_{i})$,$n$为偶数。现在重新排列这$n$组数字,得到新的$(A_{i},B_{i})$,使得下面的值最大:

$ans=\sum_{i=1}^{\frac{n}{2}}(B_{i}\sum_{j=1}^{i}A_{j})+\sum_{i=\frac{n}{2}+1}^{n}(B_{i}(X+\sum_{j=1}^{i}A_{j}))$

其中$2\leq n\leq 50,1\leq a_{i}\leq100000,1\leq b_{i}\leq10,0\leq X\leq 100000$

思路:现在考虑考虑最后分在前一半的两组$(A_{i},B_{i}),(A_{j},B_{j})$,若$i$在前优于$j$在前,那么$A_{i}B_{i}+(A_{i}+A_{j})B_{j}\geq A_{j}B_{j}+(A_{i}+A_{j})B_{i}$,即$A_{i}B_{j}\geq A_{j}B_{i}$。

由于$b_{i}$较小,现在枚举最后后一半的数字的所有的$A_{i}$之和$S$,那么现在对于一个数对,可以直接枚举它在前一半还是后一半(现在不管它在前一半还是后一半都可以直接计算对答案的贡献),这样可以进行动态规划。令$f[i][j][k]$表示现在已经考虑了$i$个数字,后一半数字的个数为$j$,后一半数字的$B$之和为$k$能得到的最大值,答案为$f[n][n/2][S]$。

#include <stdio.h>
#include <string>
#include <stack>
#include <vector>
#include <string.h>
#include <algorithm>
#include <assert.h>
using namespace std; int cmp(pair<int,int> a,pair<int,int> b)
{
return a.first*b.second<b.first*a.second;
} int f[55][33][505]; int A[55],B[55]; void up(int &x,int y)
{
if(x<y) x=y;
} int n; void DP(const int NextSumB,const int X)
{
memset(f,-1,sizeof(f));
f[0][0][0]=0;
int pre=0;
for(int i=1;i<=n;++i)
{
pre+=B[i];
for(int j=0;j<=n/2;++j) for(int k=0;k<=pre;++k)
{
if(f[i-1][j][k]>=0)
{
up(f[i][j][k],f[i-1][j][k]+A[i]*(pre-k)+A[i]*NextSumB);
up(f[i][j+1][k+B[i]],f[i-1][j][k]+A[i]*B[i]+A[i]*k+X*B[i]);
}
}
}
} class Moneymanager {
public:
int getbest(vector<int> a,vector <int> b,int X) {
vector<pair<int,int> > p;
n=(int)a.size();
int sum=0;
for(int i=0;i<n;++i) {
p.push_back(make_pair(a[i],b[i]));
sum+=b[i];
}
sort(p.begin(),p.end(),cmp);
for(int i=1;i<=n;++i)
{
A[i]=p[i-1].first;
B[i]=p[i-1].second;
} int ans=0;
for(int i=0;i<=sum;++i)
{
DP(i,X);
ans=max(ans,f[n][n/2][i]);
} return ans;
}
};

  

topcoder srm 691 div1 -3的更多相关文章

  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. 阿里云云盾服务证书免费CA证书申请与配置 (原)

    申请入口(首页导航产品->安全->CA证书服务->立即购买) 免费版选择步骤一步一步来 1.品牌选 Symantec 2.保护类型选择 一个域名(免费版只能一个好像) 3.证书类型选 ...

  2. Exception in Spark

    1: Exception in thread "main" org.apache.spark.SparkException: org.apache.spark.streaming. ...

  3. mysql 5.6 分区与不分区的区别

    mysql> CREATE TABLE t1 ( id INT, date DATETIME DEFAULT CURRENT_TIMESTAMP) ENGINE=Innodb; Query OK ...

  4. 执行字符串或注释代码段的方法(eval、exec、execfile)

    eval:计算字符串中的表达式exec:执行字符串中的语句execfile:用来执行一个文件 需注意的是,exec是一个语句,而eval()和execfile()则是内建built-in函数. 1 2 ...

  5. 在linux中配置mysql的过程

    以华为企业云中的CentOS 7 为例. 1. 首先要安装相应的包,这个使用各种linux发行版的包管理工具就行,不再赘述.有一点需要注意,现在许多linux发行版将mariadb作为MySQL的默认 ...

  6. python 测试文件或者文件目录是否存在 测试文件类型,获取文件大小,获取修改日期

    ----测试一个文件或目录是否存在 >>> import os >>> os.path.exists('/etc/passwd') True >>> ...

  7. C# CheckBox与RadioButton

    通常RadioBox称为单选按钮,CheckBox称为多选按钮,这两个控件都是从ButtonBase类中派生,可以将其视为按钮. 多个checkBox之间的选择是互相独立的,互补影响.多个RadioB ...

  8. python 实现有序字典

    python 实现有序字典 Python默认的字典,是不按顺序存储.输出我们添加在字典中的内容的,即是无序的字典.python 使用OrderedDict函数实现有序的字典. 示例: d = dict ...

  9. [转载]Oracle PL/SQL之LOOP循环控制语句

    在PL/SQL中可以使用LOOP语句对数据进行循环处理,利用该语句可以循环执行指定的语句序列.常用的LOOP循环语句包含3种形式:基本的LOOP.WHILE...LOOP和FOR...LOOP. LO ...

  10. [转载]转,Oracle中关于处理小数点位数的几个函数,取小数位数,Oracle查询函数

    关于处理小数点位数的几个oracle函数() 1. 取四舍五入的几位小数 select round(1.2345, 3) from dual; 结果:1.235 2. 保留两位小数,只舍 select ...