mobius的奇怪演绎

当我第一眼看见题目中出现mobius的时候,我唯一想到的就是某科学家对于n维空间的阐述与思考,同时还提出了一个mobius环。而这道题中的环就是mobius环咯。不过其实这是一道dp。。。dp的思路还是比较神。。。左括号设为+1,右括号-1.首先前面和后面有对应的规则,那么我们就做一个四维dp(dp[i][j][m][k])i表示位置,j表示正面的左括号和右括号之和,m是背面的和的最小值的abs,k是背面的和。记录m的是因为可能出现如下情况:
__________  (mid) ________      __
    +100                       -200        +100  
虽然l+r = 0 但是其实这是不合法的。所以dp到最后的时候就需要考虑两个条件:
1. j >= m            2. j+k == 0  
转移呢?分情况讨论:
1.s[i+1] == 'S' 这种情况下肯定有dp[i+1][j+1][m][k+1] += dp[i][j][m][k];
             而上面是j + 1,而j-1取决于j是否大于0,而且这时还需要考虑k + m == 0如果为0,那么m就要更新
                  so: if(k + m == 0) dp[i+1][j-1][m+1][k-1] += dp[i][j][m][k];
                          else dp[i+1][j-1][m][k-1] +=dp[i][j][m][k];
2,s[i+1]=='D' 
        如果j+1,那么k--,如上考虑k与m的关系。 然后j-1只考虑j>0 方程参上或代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstdio>
  5. #include <cstring>
  6. using namespace std;
  7. typedef long long ll;
  8. int T;
  9. ll dp[][][][];
  10. char s[]; int n = ;
  11. int main()
  12. {
  13. freopen("mobius.in","r",stdin);
  14. freopen("mobius.out","w",stdout);
  15. scanf("%d",&T);
  16. getchar();
  17. while(T--)
  18. {
  19. n = ;
  20. scanf("%s",s+);
  21. n = strlen(s+);
  22. memset(dp,,sizeof(dp));
  23. dp[][][][n+] = ;
  24. for(int i = ; i < n; i++)
  25. for(int j = ; j <= i; j++)
  26. for(int m = ; m <= i; m++)
  27. for(int k = -m+n+; k <= i+n+; k++)
  28. {
  29. if(dp[i][j][m][k])
  30. {
  31. if(s[i+] == 'S'){
  32. dp[i+][j+][m][k+] += dp[i][j][m][k];
  33. if(j)
  34. {
  35. if(m == -(k-n-)) dp[i+][j-][m+][k-] += dp[i][j][m][k];
  36. else dp[i+][j-][m][k-] += dp[i][j][m][k];
  37. }
  38. }
  39. else{
  40. if(j) dp[i+][j-][m][k+] += dp[i][j][m][k];
  41. if(m == -(k-n-)) dp[i+][j+][m+][k-] += dp[i][j][m][k];
  42. else dp[i+][j+][m][k-] += dp[i][j][m][k];
  43. }
  44. }
  45. }
  46. ll ans = ;
  47. for(int i = ; i <= n;i++)
  48. for(int j = ; j <= i;j++)
  49. ans += dp[n][i][j][-i+n+];
  50. printf("%lld\n",ans);
  51. }
  52. return ;
  53. }

mobius

某不科学的多重背包

题目:Eden 的新背包问题

【问题描述】

“寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心情。能不能说给我听。”

失忆的 Eden 总想努力地回忆起过去,然而总是只能清晰地记得那种思念的感觉,却不能回忆起她的音容笑貌。

记忆中,她总是喜欢给 Eden 出谜题:在 valentine’s day 的夜晚,两人在闹市中闲逛时,望着礼品店里精巧玲珑的各式玩偶,她突发奇想,问了 Eden 这样的一个问题:有 n 个玩偶,每个玩偶有对应的价值、价钱,每个玩偶都可以被买有限次,在携带的价钱m 固定的情况下,如何选择买哪些玩偶以及每个玩偶买多少个,才能使得选择的玩偶总价钱不超过 m,且价值和最大。

众所周知的, 这是一个很经典的多重背包问题,Eden 很快解决了,不过她似乎因为自己的问题被飞快解决感到了一丝不高兴,于是她希望把问题加难:多次询问,每次询问都将给出新的总价钱,并且会去掉某个玩偶(即这个玩偶不能被选择),再问此时的多重背包的答案(即前一段所叙述的问题)。

这下 Eden 犯难了,不过 Eden 不希望自己被难住,你能帮帮他么?

【输入格式】

从文件 bag.in 看读入数据。

第一行一个数 n,表示有 n 个玩偶,玩偶从 0 开始编号

第二行开始后面的 n 行,每行三个数 ai, bi, ci,分别表示买一个第 i 个玩偶需要的价钱,获得的价值以及第 i 个玩偶的限购次数。

接下来的一行为 q,表示询问次数。

接下来 q 行,每行两个数 di, ei表示每个询问去掉的是哪个玩偶(注意玩偶从 0 开始编号)以及该询问对应的新的总价钱数。(去掉操作不保留,即不同询问互相独立)

【输出格式】

输出到文件 bag.out 中。

输出 q 行,第 i 行输出对于第 i 个询问的答案。

【样例输入】

5

2 3 4

1 2 1

4 1 2

2 1 1

3 2 3

5

1 10

2 7

3 4

4 8

0 5

【样例输出】

13

11

6

12

4

【样例说明】

一共五种玩偶, 分别的价钱价值和限购次数为(2,3,4), (1,2,1), (4,1,2),(2,1,1),(3,2,3)。

五个询问,以第一个询问为例。第一个询问表示的是去掉编号为 1 的玩偶,且拥有的钱数为 10 时可以获得的最大价值,则此时剩余玩偶为(2,3,4),(4,1,2),(2,1,1),(3,2,3),若把编号为 0 的玩偶买 4 个(即全买了) ,然后编号为 3 的玩偶买一个, 则刚好把 10元全部花完, 且总价值为 13。 可以证明没有更优的方案了。

注意买某种玩偶不一定要买光。

【数据规模与约定】

10%数据满足 1 ≤ n ≤ 10;

另 20%数据满足 1 ≤ n ≤ 100, ci = 1, 1 ≤ q ≤ 100;

另 20%数据满足 1 ≤ n ≤ 100, 1 ≤ q ≤ 100;

另 30%数据满足 ci = 1;

100%数据满足 1 ≤ n ≤ 1000, 1 ≤ q ≤ 3*105,1 ≤ ai、bi、ci ≤ 100, 0 ≤ di < n,  0 ≤ ei ≤ 1000。

为什么一开始要贴题目呢?因为这道题原来bzoj上面有,现在被他们封权限了,要交钱才能看。so,以后看方便(bzoj丧心病狂,原来的良心呢?)
    贴这道题主要是因为几点启示:
    1.一定要注意空间的问题,并且c++ 如果开小了有可能不会re。。坑!
    2.看到如此的询问,直接考虑预处理吧。这道题利用只有一个物品会被ban掉,所以就预处理出1-i,容量为j的最大价值和i-n,容量为j的最大价值。注意这里是可以递推的。f[i][j] = f[i-1][j] 然后在在现在的i物品上dp,减少计算量。不减少——手测比暴力还低。。。
    3.注意编号问题!

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. using namespace std;
  6.  
  7. int n,q;
  8. int num[],w[],v[];
  9. int f[][];
  10. int g[][];
  11.  
  12. int main()
  13. {
  14. freopen("bag.in","r",stdin);
  15. freopen("bag.out","w",stdout);
  16. scanf("%d",&n);
  17. memset(f,,sizeof(f));
  18. memset(g,,sizeof(g));
  19. memset(num,,sizeof(num));
  20. memset(w,,sizeof(w));
  21. memset(v,,sizeof(v));
  22. for(int i = ; i <= n; i++)
  23. scanf("%d%d%d",&w[i],&v[i],&num[i]);
  24. for(int i = ; i <= n; i++)
  25. {
  26. for(int j = ; j <= ; j++)
  27. f[i][j] = f[i-][j];
  28. for(int k = ;k <= num[i];k++)
  29. for(int t = ;t >= ; t--)
  30. if(t >= w[i]) f[i][t] = max(f[i][t],f[i][t-w[i]]+v[i]);
  31. }
  32. for(int i = n;i >;i--)
  33. {
  34. for(int j = ; j <= ; j++)
  35. g[i][j] = g[i+][j];
  36. for(int k = ; k <= num[i];k++)
  37. for(int t = ; t >= ; t--)
  38. if(t >= w[i]) g[i][t] = max(g[i][t],g[i][t-w[i]]+v[i]);
  39. }
  40. scanf("%d",&q);
  41. while(q--)
  42. {
  43. int t,mark;
  44. scanf("%d%d",&mark,&t);
  45. mark ++;
  46. if(mark == ) printf("%d\n",g[][t]);
  47. else if(mark == n) printf("%d\n",f[n-][t]);
  48. else{
  49. int ans = ;
  50. for(int j = ; j <= t;j++)
  51. ans = max(ans,f[mark-][j]+g[mark+][t-j]);
  52. printf("%d\n",ans);
  53. }
  54. }
  55. return ;
  56. }

bag

bzoj 刷题路

首先跪拜hja。
    跪毕,起身说正事。今天我竟然调了一个早上的1001,然后又调了一个晚上的1002,我是不是没救了。。
    第一道题,就是某周大神在2007还是08年的的某ppt中的最大最小定理解析,其中提到了s-t平面图用对偶图的方法来做,不过原理我不怎么太懂,也就是不会推导,所以只能是比较弱的记录下来。根据Symon Yang的说法,这种题的图都相当的规整,所以对于对偶面的确定一般比较简单。不过既然在标号上降低难度,那么点基本都是10^6级的了,so,想到用对偶图的边来表示割,然后跑一遍spfa或dijkstra+heap就可以了。不过由于对自己的dijkstra毫无信心,所以我还是spfa算了。那么有什么注意的呢?那就是慢慢推导编号,不要捉急,慢慢来。还有如果是spfa要开一个循环队列,只需要在下标那里mod一个点数就好。(为什么是点数呢?因为如果开小了那么又可能前面的某些没有出列的元素被覆盖掉了,导致算法出错(我会告诉你我调了一个小时吗?)其余倒没什么了。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. using namespace std;
  6. int n,m;
  7. int heng[][],shu[][],xie[][];
  8. struct edge{
  9. int t,d;
  10. edge* next;
  11. }e[],*head[];
  12. int ne = ;
  13. void addedge(int f,int t,int d)
  14. {
  15. e[ne].t = t,e[ne].d = d;
  16. e[ne].next = head[f];
  17. head[f] = e + ne++;
  18. e[ne].t = f,e[ne].d = d;
  19. e[ne].next = head[t];
  20. head[t] = e + ne++;
  21. }
  22. int s,t;
  23. int dis[];
  24. bool in[];
  25. int q[];
  26. int l,r;
  27. int spfa(int s,int t)
  28. {
  29. int ql=;
  30. memset(dis,0x3f3f3f3f,sizeof(dis));
  31. memset(in,false,sizeof(in));
  32. memset(q,,sizeof(q));
  33. in[s] = true;
  34. l = , r = ;
  35. q[r++ % ql] = s;
  36. dis[s] = ;
  37. while(l < r)
  38. {
  39. int now = q[l++ % ql];
  40. in[now] = false;
  41. for(edge* p = head[now];p;p = p->next)
  42. if(dis[p->t] > dis[now] + p->d){
  43. dis[p->t] = dis[now] + p->d;
  44. if(in[p->t] == false) {
  45. q[r++ % ql] = p->t,in[p->t] = true;
  46. }
  47. }
  48. }
  49. return dis[t];
  50. }
  51. int main()
  52. {
  53. freopen("cs.in","r",stdin);
  54. memset(heng,,sizeof(heng));
  55. memset(shu,,sizeof(shu));
  56. memset(head,NULL,sizeof(head));
  57. scanf("%d%d",&n,&m);
  58. if( n == || m == )
  59. {
  60. int k = max(n,m);
  61. int ans = 0x3f3f3f3f;
  62. for(int i = ; i < k; i++)
  63. {
  64. int x;
  65. scanf("%d",&x);
  66. ans = min(ans,x);
  67. }
  68. printf("%d",ans);
  69. return ;
  70. }
  71. for(int i = ;i <= n; i++)
  72. for(int j = ; j < m; j++)
  73. scanf("%d",&heng[i][j]);
  74. for(int i = ; i <= n-;i++)
  75. for(int j = ; j <= m; j++)
  76. scanf("%d",&shu[i][j]);
  77. for(int i = ; i <= n-;i++)
  78. for(int j = ; j <= m-;j++)
  79. scanf("%d",&xie[i][j]);
  80. s = ;
  81. t = n*(m-) + m*(n-) + (m-)*(n-) - n * m + ;
  82. for(int i = ; i <= n; i++)
  83. for(int j = ;j < m; j++)
  84. {
  85. if(i == ){addedge(t,(i-)*(m-)*+j*,heng[i][j]);}
  86. else if( i == n) {addedge((i-)*(m-)*+j*-,s,heng[i][j]);}
  87. else addedge((i-)*(m-)*+j*,(i-)*(m-)*+j*-,heng[i][j]);
  88. }
  89. for(int i = ; i < n; i++)
  90. for(int j = ; j <= m; j++)
  91. {
  92. if(j == ){addedge(s,(i-)*(m-)*+(j-)*+,shu[i][j]);}
  93. else if( j == m){addedge(t,(i-)*(m-)*+(j-)*,shu[i][j]);}
  94. else addedge((i-)*(m-)*+(j-)*,(i-)*(m-)*+(j-)*+,shu[i][j]);
  95. }
  96. for(int i = ; i < n; i++)
  97. for(int j = ; j < m;j++)
  98. addedge((i-)*(m-)*+(j-)*+,(i-)*(m-)*+j*,xie[i][j]);
  99. printf("%d\n",spfa(s,t));
  100. return ;
  101. }

注意数组一定不要开小了,我re了7次还是8次。。。

还有就是1002这道神题。这道题第一要知道递推式,然后还要写高精。像这种找规律我一般都跪了。。不过这个题找递推式的正确方法是基尔霍夫矩阵来求,有时间再探讨好了,我还是不要作死了,no zuo no die。。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. int n;
  7. int a[];
  8. int b[];
  9. int len1, len2;
  10. void cal()
  11. {
  12. int temp[];
  13. memset(temp,,sizeof(temp));
  14. int len = ;
  15. for(int i = ; i < len1;i++)
  16. {
  17. temp[i] += a[i]*;
  18. temp[i+] += temp[i]/;
  19. temp[i] = temp[i]%;
  20. }
  21. if(temp[len1] != ) len = len1 + ;
  22. else len = len1;
  23. for(int i = ; i < min(len,len2);i++)
  24. {
  25. if(temp[i] < b[i]) temp[i+]--,temp[i]+= ;
  26. temp[i] = temp[i] - b[i];
  27. }
  28. if(temp[len-] == ) len--;
  29. temp[] += ;
  30. int now = ;
  31. while(temp[now] >= ){temp[now+] += , now++;temp[now-] %= ;}
  32. if(now == len) len++;
  33. int t[];
  34. for(int i = ; i < len1;i++)
  35. t[i] = a[i];
  36. for(int i = ; i < len;i++)
  37. a[i] = temp[i];
  38. for(int i = ; i < len1;i++)
  39. b[i] = t[i];
  40. len2 = len1;
  41. len1 = len;
  42. }
  43. int main()
  44. {
  45. scanf("%d",&n);
  46. a[] = ;
  47. b[] = ;
  48. len1 = ;
  49. len2 = ;
  50. for(int i = ; i <= n;i++)
  51. cal();
  52. for(int i = len1 - ; i >= ; i--)
  53. printf("%d",a[i]);
  54. }

高精真是写死人。。要不是省选只能用c,c++,pascal果断python,java(其实主要我不会java和python = =b。。。)
不过张老师给我说了一个dp:
    对于第i个点,然后进行分割,相当于这一状态的某种情况是由某两种已知的情况拼出来的。。。。只能说。。我明天再去问问。。
再跪hja!

【集合!】 20140416 && 20140417集训 总结的更多相关文章

  1. Loj #2331. 「清华集训 2017」某位歌姬的故事

    Loj #2331. 「清华集训 2017」某位歌姬的故事 IA 是一名会唱歌的女孩子. IOI2018 就要来了,IA 决定给参赛选手们写一首歌,以表达美好的祝愿.这首歌一共有 \(n\) 个音符, ...

  2. OI暑假集训游记

    莞中OI集训游记 Written BY Jum Leon. I        又是一载夏,本蒟蒻以特长生考入莞中,怀着忐忑的心情到了8月,是集训之际.怀着对算法学习的向往心情被大佬暴虐的一丝恐惧来到了 ...

  3. 雅礼集训【Day6-1】字符串

    雅礼集训[Day6-1]字符串 假设我们有串\(a\),我们设\(a'\)为\(a\)翻转后按为取反过后的串. 我们只考虑前一半的,长为\(m\)的串.如果前半截匹配了\(a\)或者\(a'\),则\ ...

  4. 「2017 山东一轮集训 Day5」苹果树

    「2017 山东一轮集训 Day5」苹果树 \(n\leq 40\) 折半搜索+矩阵树定理. 没有想到折半搜索. 首先我们先枚举\(k\)个好点,我们让它们一定没有用的.要满足这个条件就要使它只能和坏 ...

  5. 路飞学城-Python开发集训-第3章

    学习心得: 通过这一章的作业,使我对正则表达式的使用直接提升了一个level,虽然作业完成的不怎么样,重复代码有点多,但是收获还是非常大的,有点找到写代码的感觉了,遗憾的是,这次作业交过,这次集训就结 ...

  6. 【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)

    [UOJ#340][清华集训2017]小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划) 题面 UOJ 洛谷 题解 考虑如何暴力\(dp\). 设\(f[i][a][b][c]\)表示当前到了第\(i\) ...

  7. [2018HN省队集训D9T1] circle

    [2018HN省队集训D9T1] circle 题意 给定一个 \(n\) 个点的竞赛图并在其中钦定了 \(k\) 个点, 数据保证删去钦定的 \(k\) 个点后这个图没有环. 问在不删去钦定的这 \ ...

  8. 2017-12 CDQZ集训(已完结)

    从联赛活了下来(虽然分数倒一……),接下来要去CDQZ集训啦…… DAY -2 2017-12-16 被老师安排负责一部分同学的住宿以及安排…… 抓紧时间继续学习,LCT真好玩啊真好玩…… 晚上放假了 ...

  9. 7.30 正睿暑期集训营 A班训练赛

    目录 2018.7.30 正睿暑期集训营 A班训练赛 T1 A.蔡老板分果子(Hash) T2 B.蔡老板送外卖(并查集 最小生成树) T3 C.蔡老板学数学(DP NTT) 考试代码 T2 T3 2 ...

随机推荐

  1. Codeforces 1167F 计算贡献

    题意:给你一个函数f,计算∑(i = 1 to n)(j = i to n) f(i, j).f(i, j)的定义是:取出数组中i位置到j位置的所有元素,排好序,然后把排好序的位置 * 元素 加起来. ...

  2. std::wcout输出1遍不输出

    std::wcout输出1遍不输出 程序明明在执行地方执行 wcout无法输出到控制台 cout就可以 添加中文支持即可

  3. Dubbox离线约束地址

    地址: http://code.alibabatech.com/schema/dubbo/dubbo.xsd

  4. Java中有几种类型的流?

    (1)字节流 InputStream/OutputStream ①FileInputStream/FileOutputStream:文件字节流,用于文件的读写操作 ②BufferedInputStre ...

  5. 安卓8.0真机运行appium1.4遇到的问题:运行自动化脚本,手机自动安装 settings.apk和unclock.apk,执行脚本时提示安装UnicodeIME-debug.apk失败,怎么关掉自动安装?

    运行自动化脚本,手机自动安装 settings.apk和unclock.apk,执行脚本时提示安装UnicodeIME-debug.apk失败,怎么关掉自动安装? 这3个apk的目录分别是: D:\P ...

  6. Magento站点优化方案

    Magento 是一个开源电子商务系统,尤其以扩展性高著称,但是很高的扩展性往往是牺牲了速度为代价的,虽然现在magento为速度提升做了很多工作,但是还是没能达到人们对速度的要求.既然如此还是很自然 ...

  7. 「NOI2016」循环之美(小性质+min_25筛)

    传送门. 题解 感觉这题最难的是第一个结论. x/y首先要互质,然后如果在10进制是纯循环小数,不难想到y不是2.5的倍数就好了. 因为十进制下除以2和5是除得尽的. 必然会多出来的什么东西. 如果是 ...

  8. Vlan的相关知识点收纳

    Q.思科Vlan的上限个数是多少? VLAN的范围:根据平台和软件版本不同,Cisco交换机最多支持4096个VLAN.VLAN号共有4096个,0-4095    0,4095:这两个号保留,仅限系 ...

  9. delphi 文件分割与合并

    流的使用分割与合并文件的函数 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, ...

  10. spring AOP (使用AspectJ的xml方式 的aop实现) (7)

    目录 一.定义计算器接口跟实现类 二.定义两个切面,日志切面和验证切面 三.在xml中配置切面 四.测试类 一.定义计算器接口跟实现类 public interface ArithmeticCalcu ...