TopCoder SRM469C: TheMoviesLevelThreeDivOne 题解

标签: TopCoder dp
3人阅读 评论(0) 收藏 举报
分类:

很好的dp题目
我们尝试推断某一个人A能不间断的看完电影的条件
易得,A想要在看完B的第i-1部电影之后不间断的看B的第i部电影,应该满足以下条件:k=1AtotA[xk]+k=1i1A[yk]k=1iB[yk]0
那我们如果想求A,B均能顺利看完的方案数,考虑dp,大概要记录A的当前和,B的当前和,上面的式子对于A来说的历史最小值和对于B来说的历史最小值,每个状态的级别都是1000的,这样是O(10004)的复杂度,不能接受
考虑怎么优化这个dp
我们可以发现一个性质:A和B中总有一个人能看完所有的电影,因为考虑A和B原来自己手上的电影,总有一个人会先看完自己手上原来的电影,另一个人后看完,那么那个后看完的人看完自己手上原来的电影以后,另一个人的电影一定已经全部看好放在他的队列里面了。也就是说,后看完自己手上原来的的电影的人一定能看完所有的电影
我们考虑用总方案数减去有人被卡住的方案数,由上面一段可知最多只会有一个人卡住,所以答案是AB
这样再用dp算,就可以缩减掉很多状态
令dp[i][j][k]表示当前考虑到第i部电影,对于1~i-1的所有位置,上面的多项式的值的最小值是j,当前的值是k的方案数。注意上面的多项式中的sigma(A)是动态变化的
转移有两种:
1. 第i部电影放入A的queue,那么之前的1~i的所有位置的值由于sigma(A)都要加上a[i],所以dp[i][j][k]dp[i+1][j+a[i]][k+a[i]]
2. 第i部电影放入B的queue,我们考虑用当前的k减去b[i]来更新历史最小值,并且k加上a[i]-b[i]

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<int,int>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const int MOD=1e9+7;
const LL LINF=2e16;
const int INF=2e9;
const int magic=348;
const double eps=1e-10;
const double pi=acos(-1);

inline int getint()
{
    char ch;int res;bool f;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

LL dp[2][2048][2048];
int a[148],b[148];

class TheMoviesLevelThreeDivOne
{
    int n;
    const int MMAX=1000;
    inline LL calc()
    {
        int cur=0,nxt=1,i,j,k;
        memset(dp[0],0,sizeof(dp[0]));
        dp[0][MMAX][MMAX]=1;
        for (i=1;i<=n;i++)
        {
            memset(dp[nxt],0,sizeof(dp[nxt]));
            for (j=MMAX-20*i;j<=MMAX;j++)
                for (k=MMAX-20*i;k<=MMAX+20*i;k++)
                    if (dp[cur][j][k])
                    {
                        //add i to y
                        dp[nxt][min(MMAX,j+b[i])][k+b[i]]+=dp[cur][j][k];
                        //add i to x
                        dp[nxt][min(j,k-a[i])][k+b[i]-a[i]]+=dp[cur][j][k];
                    }
            swap(cur,nxt);
        }
        LL res=0;
        for (j=MMAX-20*n;j<=MMAX-1;j++)
            for (k=MMAX-20*n;k<=MMAX+20*n;k++)
                res+=dp[cur][j][k];
        return res;
    }                   
    public:
        inline LL find(vector<int> A,vector<int> B)
        {
            n=int(A.size());int i;
            for (i=1;i<=n;i++) a[i]=A[i-1],b[i]=B[i-1];
            LL res=calc();
            for (i=1;i<=n;i++) swap(a[i],b[i]);
            res+=calc();
            return (1ll<<n)-res;
        }
};

/*---Debug Part---*/
int main ()
{
    TheMoviesLevelThreeDivOne A;
    int nn;vector<int> aa,bb;
    while (scanf("%d",&nn)!=EOF)
    {
        register int i,x;
        aa.clear();bb.clear();
        for (i=1;i<=nn;i++) x=getint(),aa.pb(x);
        for (i=1;i<=nn;i++) x=getint(),bb.pb(x);
        printf("%lld\n",A.find(aa,bb));
    }
    return 0;
}
查看评论

2018软考系统集成项目管理工程师视频教程 案例分析精讲

-
  • 1970年01月01日 08:00

Topcoder好题推荐 ( 持续更新中)

推荐的好题不一定是难题,但往往带有那么一点代表性。凡是由别人推荐的题目,偶会加上推荐人ID和blog地址。偶自己推荐的题目,偶会尽量推荐一份简洁的代码。当天推荐的题会以红色标记。 Single ...
  • piaocoder
  • piaocoder
  • 2016-04-01 17:06:24
  • 1033

Topcoder:SRM 708 算法题解

题目翻译 250分题目:SafeBetting 赌徒有b块钱,他想把自己手上的钱增加到c块,同时他又不想输的太惨,因此必须保证每次下注后手上不少于a块钱。每次下注,赢了则下注的钱按双倍奉...
  • Hans__Yang
  • Hans__Yang
  • 2017-02-11 11:21:07
  • 754

Topcoder SRM 701 算法分析求解

Problem 250 题目:排序子集 有一个数组,要将其变成不减序列,求需要修改的元素的个数。 分析求解:直接对数组进行排序,对比排序后的数组和排序前的数组,统计二者不一致的元素的个数即可。 ...
  • Hans__Yang
  • Hans__Yang
  • 2016-09-27 23:49:03
  • 279

topcoder 刷题笔录 初级篇(一)

摘要:本系列文章为在topcoder上的刷题记录和心得,计划刷题500道。其中,初级题目30道,撰文三篇;中级题目60道,撰文六篇;其他高级题目100道,撰文10篇。 1.题目1——SRM146 ...
  • trochiluses
  • trochiluses
  • 2013-12-20 16:00:56
  • 2713

Topcoder介绍及Arena使用方法

  • 2008年05月25日 00:22
  • 657KB
  • 下载

发现jsf + spring在jboss中的一个问题

在web.xml中指定spring配置文件位置时:         contextConfigLocation         classpath:applicationContext*.xm...
  • lhch1984
  • lhch1984
  • 2011-08-15 10:57:31
  • 292

TopCoder SRM 701 div1. 900 FibonacciStringSum - 矩阵乘法

初赛大原题!(雾   稍微推一推就可以得到要算的式子是   ∑k(n+1−kk)kb(n−k)a\sum_{k} \binom{n+1-k}{k}k^b (n-k)^a   可以用二项式定理展开...
  • GEOTCBRL
  • GEOTCBRL
  • 2016-11-03 21:22:19
  • 436

topcoder Arena配置及基本使用方法

由于想着多做比赛增加实力,而且总感觉topcoder听起来知名度比codeforces高 所以开始注册、配置 搞了这么久总算搞好了,所以想分享下经验,帮助大家少走点弯路 我是在lin...
  • u011639256
  • u011639256
  • 2014-07-27 09:56:38
  • 4524

TopCoder 规则入门

1.基本规则2.运行环境3.注册与登陆4.界面简介5.练习6.比赛7.注意事项TopCoder(以下简写tc) URL: http://www.topcoder.com1.基本规则tc的比赛规则归结...
  • touzani
  • touzani
  • 2007-05-23 04:19:00
  • 5086
    个人资料
    持之以恒
    等级:
    访问量: 9620
    积分: 1489
    排名: 3万+
    最新评论