A

  树形dp是看起来比较靠谱的做法 , 但是转移的时候不全面就会出错 , 从贪心的角度出发 , 首先让第一量车走最长路,

  然后就会发现递归结构 , 得到递归式 f[i] = ( f[i-2] + f[i-3] + .. + f[1]) * 2 + 1;

  贪心的正确性 , 可以根据dp方程证出来 , 不过还是蛮显然的...

  

 #define maxn 1000100
#define mod 1000000007
#define INF (1ll<<60)
llong dp[maxn][];
class TrafficCongestion {
public:
int theMinCars(int);
}; llong dfs(int h,int s)
{
int i,j;
llong resa,resb,resc;
dp[][] = ;
dp[][] = ;
dp[][] = ;
for ( i= ; i<=h ; i++ )
for ( j= ; j< ; j++ )
{
resa = resb =resc = INF;
if (j==)
{
resa = dp[i-][] + dp[i-][] + 1ll; resa %= mod;
resb = dp[i-][] + dp[i-][]; resb %= mod;
resc = dp[i-][] + dp[i-][]; resc %= mod;
}
else if (j==)
{
resa = dp[i-][] * 2LL % mod;
resb = dp[i-][] + dp[i-][]; resb %= mod;
}
else if (j==)
{
resa = dp[i-][] + dp[i-][]; resa %= mod;
resb = dp[i-][]*2LL + 1LL; resb %= mod;
}
resa = min(resa,resb);
resa = min(resa,resc);
dp[i][j] = resa;
}
return dp[h][s];
}
int TrafficCongestion::theMinCars(int h)
{
memset(dp,-,sizeof(dp));
llong ans = dfs(h,);
return ans;
}

B

  假设每个value只有一个 , 那么只要构造递增次数为K的序列就行了 ,  构造方法可以是:先取前k个作为k个递增序列的起点 ,

  剩下的就是n-k个元素分配给,k个集合求方案数 , 但是这样无法保证每个序列递增 ,不过还是给我们一个启示:按递增顺序考虑.

  定义dp[i][j] 为 前i个元素 , 已经构造了j个递增序列的方案数.

  dp[i+1][j] = dp[i][j] *  j + dp[i][j-1]

  拓展到每个value可能出现多个的情况时 ,转移要乘上组合数.

 using namespace std;
#define maxn 1300
typedef long long llong;
const llong mod = ;
class LISNumber {
public:
int count(vector <int>, int);
};
llong dp[][maxn],c[maxn][maxn];
int n,sum[maxn];
int LISNumber::count(vector <int> card, int K)
{
int i,j,k;
n = card.size();
for ( i= ; i<n ; i++ ) sum[i] = i? sum[i-]+card[i] : card[i]; for ( i=,c[][]= ; i<maxn ; i++ )
for ( j= ; j<=i ; j++ )
{
c[i][j] = j?c[i-][j-]+c[i-][j] : ;
c[i][j] %= mod;
} memset(dp,,sizeof(dp));
dp[][] = ;
for ( i= ; i<n ; i++ )
for ( j= ; j<=sum[i] && j<=K ; j++ ) if (dp[i][j])
{
// printf("dp[%d][%d]=%lld\n",i,j,dp[i][j]);
for ( k= ; k<=j && k<=card[i] ; k++ )
{
llong pos,add,x;
add = card[i]-k;
pos = ( (i?sum[i-]:) + ) - j + k;
x = c[j][k] * c[pos+add-][pos-] %mod * dp[i][j] % mod;
// printf("add to dp[%d][%d] ,k=%d: %lld\n",i+1,(int)(j+add),k,x);
dp[i+][j+add] += x;
dp[i+][j+add] %= mod;
}
}
// for ( i=0 ; i<=n ; i++ )
// for ( j=0 ; j<=K ; j++ ) if (dp[i][j]) printf("dp[%d][%d]=%lld\n",i,j,dp[i][j]);
return dp[n][K] % mod;
}

C

  (计算几何不会 , 看题解撸了好久..)

  判断点是否在三角形内部或边界:

    顺时针地考虑每条边e , 如果黑点在e下方 , 则在内部 , 否则在外部 , 用叉积判断 , 注意叉积为0的时候 ,是恰好在边界上,应判为在内部;

  统计方案数:

    为了不重复统计 , 3元组(a,b,c)应该为升序 .

    于是有了朴素的办法: 枚举三元组.

    然后考虑: 对于确定的a , b有一个取值范围来保证 e(a,b) 这条边合法 , c也有一个取值范围来保证 e(c,a) 这条边合法 ,

    用f(i)来表示对于点i , 能取的编号最大的点 , 很显然f(i)是递增的 , 然后根据单调性 , 利用"部分和"的技巧 , 可以o(n)统计方案数.

 #define maxn (58585*4+100)
class EnclosingTriangle {
public:
long long getNumber(int, vector <int>, vector <int>);
}; struct node {
llong x,y;
};node e[maxn];
int t,f[maxn]; llong xmult(llong x0,llong y0,llong x1,llong y1) {
return x0*y1 - x1*y0;
} llong sum , add[maxn] , addid[maxn] , front , tail , c; int check(int A,int B,vector<int>x,vector<int> y) {
node a = e[A];
node b = e[B%t];
for (int i= ; i<(int)x.size() ; i++ ) {
if (xmult(a.x-x[i],a.y-y[i],b.x-x[i],b.y-y[i])>) return ;
}
return ;
} void sub(llong d) {
sum -= (tail-front) * d;
// printf("sub: cnt=%lld cut:%lld sum:%lld\n",tail-front,(tail-front)*d,sum);
while (front<tail && add[front]-c<) {
sum -= add[front]-c;
// printf("cut:%lld count:%lld otq:%lld\n",add[front]-c,add[front],addid[front]);
front++;
}
} void ins(int b) {
add[tail] = min(f[b]+,t);
addid[tail] = b;
sum += add[tail++]-c;
} long long EnclosingTriangle::getNumber(int m, vector <int> x, vector <int> y) {
for (int i= ; i< ; i++ ) {
for (int j= ; j<m ; j++ ) {
llong ox[] = {,j,m,m-j};
llong oy[] = {j,m,m-j,};
e[t++] = (node){ox[i],oy[i]};
}
}
for (int i=,j= ; i<t ; i++ ) {
while (check(i,j,x,y)) j++;
j--;
f[i] = j;
// printf ("f[%d]=%d\n",i,j);
}
c = ;
llong res = ;
for (int a=,b= ; a<t ; a++ ) {
llong d = ; while (front<tail && addid[front]<=a) {
sum -= add[front]-c;
// printf("front:%lld tail:%lld cut:%lld sum:%lld\n",front,tail,add[front]-c,sum);
front++;
}
while (f[c]<a+t && c+<t) c++,d++;
if (f[c]<a+t) break;
sub(d);
// printf("before add :sum:%lld c:%lld\n",sum,c);
while (b<=f[a]) {
if (min(f[b]+,t)-c>=) {
ins(b);
if (b==c) res--;
}
b++;
}
res += sum;
// printf("after add: sum:%lld c:%lld b:%d res:%lld\n",sum,c,b,res);
}
return res;
}

  

SRM 585 DIV1的更多相关文章

  1. SRM 585 DIV1 L2

    记录dp(i, j)表示前i种卡片的排列,使得LISNumber为j的方法数. #include <iostream> #include <vector> #include & ...

  2. topcoder srm 585 div1

    problem1 link 最优的策略就是从最低下一层开始,每两层的三个节点的子树都可以用一次遍历覆盖. problem2 link 从大到小依次放置每一种数字,并记录已经放置的数字一共有多少个$m$ ...

  3. Topcoder SRM 643 Div1 250<peter_pan>

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

  4. Topcoder Srm 726 Div1 Hard

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

  5. 图论 SRM 674 Div1 VampireTree 250

    Problem Statement      You are a genealogist specializing in family trees of vampires. Vampire famil ...

  6. SRM 583 DIV1

    A 裸最短路. class TravelOnMars { public: int minTimes(vector <int>, int, int); }; vector<int> ...

  7. SRM 590 DIV1

    转载请注明出处,谢谢viewmode=contents">http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlov ...

  8. Topcoder SRM 602 div1题解

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

  9. 状态压缩DP SRM 667 Div1 OrderOfOperations 250

    Problem Statement      Cat Noku has just finished writing his first computer program. Noku's compute ...

随机推荐

  1. 初学者学Java(十五)

    再谈数组 在这一篇中我们来讲一下关于数组的排序和查找的方法. 排序 说到数组的排序,就不得不说冒泡这种经典的方法. 1.冒泡排序 冒泡排序的基本思想是比较两个相邻元素的值,如果满足条件就交换元素的值( ...

  2. [Angular 2] ngrx/store

    @ngrx/store builds on the concepts made popular by Redux and supercharges it with the backing of RxJ ...

  3. Oracle&#39;s Business Intelligence Applications Configuration Manager 基本概念

    Oracle's Business Intelligence Applications Configuration Manager :BIACM Once the BIAPPS installatio ...

  4. Android 出现警告Exported service does not require permission

    在配置Android清单文件的时候,配置service,或者activity,或者receive的时候,出现Exported service does not require permission警告 ...

  5. JBoss 系列九十九:Rest WebService jBPM 6 集成演示样例

    概述 jBPM 6 提供 Rest API 供第三方应用整合使用 jBPM 6,本文演示假设通过 Rest API: 启动流程 获取流程实例信息 启动 User Task 完毕 User Task j ...

  6. Android(java)学习笔记249:ContentProvider使用之获得系统联系人信息01

    1.系统联系人的数据库(3张最重要的表) (1)raw_contacts  联系人表        保存联系人的id   contact_id (2)data 数据表       保存联系人的数据 ( ...

  7. 【网络流#7】POJ 3281 Dining 最大流 - 《挑战程序设计竞赛》例题

    不使用二分图匹配,使用最大流即可,设源点S与汇点T,S->食物->牛->牛->饮料->T,每条边流量为1,因为流过牛的最大流量是1,所以将牛拆成两个点. 前向星,Dini ...

  8. NYOJ 116士兵杀敌(二) 树状数组

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=116 士兵杀敌(一) 数组是固定的,所以可以用一个sum数组来保存每个元素的和就行,但是不 ...

  9. Linux中命令行编译java接口总是提示找不到符号的疑难杂症的解决

    今天学习java的接口,在linux的命令行下写代码练练手吧,啪啪啪一顿猛敲,写了一个接口UsbInserface,UDisk继承UsbInterface,写完了那就编译到bin目录呗. 当时写程序的 ...

  10. JavaScript: 世界上最被误解的语言|Douglas Crockford

    JavaScript: 世界上最被误解的语言 JavaScript: The Wrrrld's Most Misunderstood Programming Language Douglas Croc ...