题意:给定一个长度<=5000的二进制字符串S,以及一个初始为0的n,有一下两种操作:

1. 输出n(n>=1并且为2进制形式输出)

2.n=n+1

每次选择一种操作。。

求:1.有多少方案能构成该字符串 (%(10^9+7))

2.最少需要多少次能构成该字符串(%(10^9+7))

思路:

对于第一问:

能容易想到O(n^3)的dp

f[i][j] += f[k][i-1](其中[k,j-1]构成的数<=[i, j]组成的数,并且i,k位置为'1')

但是这样时限上显然不够,因为比较大小太耗时间了。。

由于是01串,我们可以先预处理same[i][j]表示以i开头和以j开头的数字最多多少个相同的。。这样判断就可以O(1)了

对于第二问:

还是可以用dp。。

f[i][j]表示以j结尾,[i, j]为最后一个数时最少分为几段。。思路跟上面差不多。。

但是比较大小可能需要一点技巧。。

基于最后结尾的数多一位,那么add操作次数*2,那么也就是说当最后的数很大是(add>=|S|),越小的结尾的数越优

所以,对于最后结尾的数比较小的,直接算出来,因为答案不会很大。。

否则的话,直接找结尾的数最小的就是最优解了。

当然,也可以基于上面的结论直接贪心。。

code:

 #include <bits/stdc++.h>
#define M 1000000007
#define Inf 0x3fffffff
using namespace std;
char s[];
int same[][], f[][], c[][]; inline void add(int& c, const int &a, const int& b){
c = a + b;
if (c >= M) c -= M;
} int bigger(const int& x, const int& y, const int& k){
if (y <= ) return ;
int len = same[y][x];
if (len >= k) return ;
return s[x+len] >= s[y+len];
} void solve(){
int n = strlen(s + );
for (int i = n; i >= ; --i)
for (int j = i; j <= n; ++j)
if (s[i] == s[j]) same[i][j] = same[i+][j+] + ;
else same[i][j] = ;
for (int i = ; i <= n; ++i)
f[][i] = ;
c[][] = f[][];
for (int i = ; i <= n; ++i){
for (int j = i; j > ; --j) if (s[j] == ''){
add(f[j][i], f[j][i], c[j-][min(i-j, j-)]);
if (bigger(j, j--(i-j), i-j+)){
// if (j == 11 && i == 17) printf("%d %d %d\n", j, j-1-(i-j), i-j+1);
add(f[j][i], f[j][i], f[j--(i-j)][j-]);
}
}
for (int j = i; j >= ; --j)
add(c[i][i-j+], c[i][i-j], f[j][i]);
}
int ans1 = ;
for (int i = ; i <= n; ++i)
add(ans1, ans1, f[i][n]);
for (int i = ; i <= n; ++i)
for (int j = i; j <= n; ++j) f[i][j] = Inf;
for (int i = ; i <= n; ++i)
f[][i] = ;
for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j) c[i][j] = Inf;
c[][] = ;
for (int i = ; i <= n; ++i){
for (int j = i; j > ; --j) if (s[j] == ''){
f[j][i] = min(f[j][i], c[j-][min(i-j, j-)] + );
if (bigger(j, j--(i-j), i-j+))
f[j][i] = min(f[j][i], f[j--(i-j)][j-] + );
}
for (int j = i; j >= ; --j)
c[i][i-j+] = min(c[i][i-j], f[j][i]);
}
int ans2 = Inf, x;
for (int i = n; i >= ; --i) if (f[i][n] < Inf){
if (n - i > ) break;
x = ;
for (int j = i; j <= n; ++j)
x = (x << ) + s[j] - '';
ans2 = min(ans2, x+f[i][n]);
}
if (ans2==Inf)
for (int i = n-; i >= ; --i) if (f[i][n] < Inf){
x = ;
for (int j = i; j <= n; ++j){
x = (x << ) + s[j] - '';
if (x >= M) x-=M;
}
ans2 = (x + f[i][n]) % M;
break;
}
printf("%d\n%d\n", ans1, ans2 % M);
} int main(){
while (scanf("%s", s+) != EOF){
solve();
}
}

codeforces 477D的更多相关文章

  1. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  2. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  3. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  4. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  5. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  6. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  7. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

  8. CodeForces - 696B Puzzles

    http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...

  9. CodeForces - 148D Bag of mice

    http://codeforces.com/problemset/problem/148/D 题目大意: 原来袋子里有w只白鼠和b只黑鼠 龙和王妃轮流从袋子里抓老鼠.谁先抓到白色老鼠谁就赢. 王妃每次 ...

随机推荐

  1. java.lang.NoClassDefFoundError: org/apache/ibatis/cursor/Cursor

    因为mybatis的版本和mybatis-spring的版本不兼容导致的,解决方法:mybatis的3.4.0及以上版本用mybatis-spring1.3.0及以上版本:mybatis的3.4.0以 ...

  2. BZOJ1912或洛谷3629 [APIO2010]巡逻

    一道树的直径 BZOJ原题链接 洛谷原题链接 显然在原图上路线的总长为\(2(n-1)\). 添加第一条边时,显然会形成一个环,而这条环上的所有边全部只需要走一遍.所以为了使添加的边的贡献最大化,我们 ...

  3. iOS一段文字设置多种颜色格式

    调用 [self fuwenbenLabel:contentLabel FontNumber:[UIFont systemFontOfSize:] AndRange:NSMakeRange(, ) A ...

  4. tableView中cell的复用机制

    TableView的重用机制,为了做到显示和数据分离,IOS tableView的实现并且不是为每个数据项创建一个tableCell.而是只创建屏幕可显示最大个数的cell,然后重复使用这些cell, ...

  5. 关于python的字符编码

    理论特别多,金角大王讲的非常细致和深入浅出. 我来个简短的总结: python2的编码:默认是ascii,可以改变成gbk,utf-8等,但是用什么编码写的,就存储成什么编码.如果搬到linux,默认 ...

  6. [Robot Framework] Robot Framework里面的变量怎么知道是在哪里定义的?

    看变量在哪里定义的:Ctrl+Alt+Space

  7. Python之路(第十八篇)shutil 模块、zipfile模块、configparser模块

    一.shutil 模块 1.shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中,需要打开文件 import shutil shutil.co ...

  8. 社交类APP原型模板分享——QQ

    QQ是一款社交类的APP应用——聊天软件,支持多人群聊以及丰富有趣的娱乐功能. 此模板交互效果很丰富,主要有抽屉侧拉效果,滚动内容界面.标签组切换.选择组件触发按钮状态变化.点击下拉展开列表.点击弹出 ...

  9. spring mvc 提交表单汉字乱码

    修改web.xml添加如下信息 <filter> <filter-name>characterEncodingFilter</filter-name> <fi ...

  10. The Django Book(自定义ModelAdmi类)

    默认的,管理界面下显示的东西只是 python2:def __unicode__(self): 和 python3:def __str__(self): 中返回的字段内容 想要让它更加的多元化的话 c ...