http://codeforces.com/contest/792/problem/C

这题奇葩题我居然用dp过了。

如果要模拟的话,可以用一个栈保存,保存每一个%3 = 2的pos,%3 = 1的pos,注意到题目是最多删除2个数,就能使得整个数%3=0了,如果要删除前导0的话就另外算。

那么贪心从栈顶删除,也就是先删除后面的数就行。然后需要删除2,又分两种情况,删除两个1和删除一个2。。等等,一路模拟。

比赛的时候没想到这样,也觉得很复杂,于是就dp了,虽然TLE了,但是加了一个剪枝就过了,dfs很玄

我用dp[i][j]表示,前i位中,模3后余数是j的最大合法长度,最大合法长度,也就是不能含有前导0.所以1001这样的情况求出来是无解的,需要特判一下。

那么求到了这个长度之后

题目就变成了,给出n个数字,选出k个,使得组合起来得数字%3 = 0,不能含有前导0.

我想不到好的算法,就dfs暴力了。感觉应该会超时,但是剪了剪支居然46ms

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 1e5 + ;
char str[maxn];
int dp[maxn][], lenstr; //dp出答案
vector<char>ans;
bool dfs(int cur, int now, int len, int pre) {
if (now == && len == dp[lenstr][]) return true;
if (cur == lenstr + ) return false;
if (len >= dp[lenstr][]) return false;
if (lenstr - cur + + len < dp[lenstr][]) return false;
if (str[cur] == '') {
if (pre) {
if (dfs(cur + , now, len + , )) {
ans.push_back(str[cur]);
return true;
}
return dfs(cur + , now, len, pre);
} else {
return dfs(cur + , now, len, pre);
}
} else {
if (dfs(cur + , (now + str[cur] - '') % , len + , )) {
ans.push_back(str[cur]);
return true;
}
return dfs(cur + , now, len, pre);
}
}
void work() {
scanf("%s", str + );
lenstr = strlen(str + );
memset(dp, -0x3f, sizeof dp);
dp[][] = ;
int flag = inf;
for (int i = ; i <= lenstr; ++i) {
if ((str[i] - '') % == ) flag = i;
for (int j = ; j < && i > ; ++j) {
dp[i][j] = dp[i - ][j];
}
//不是0的,自己作为一个
if (str[i] != '') dp[i][(str[i] - '') % ] = max(dp[i][(str[i] - '') % ], );
for (int j = ; j < ; ++j) {
int res = (j * + str[i] - '') % ;
dp[i][res] = max(dp[i][res], dp[i - ][j] + );
}
}
// cout << dp[lenstr][0] << endl;
if (dp[lenstr][] < && flag == inf) {
cout << - << endl;
return;
}
if (dp[lenstr][] < && flag != inf) {
cout << str[flag];
return;
}
dfs(, , , );
reverse(ans.begin(), ans.end());
for (int i = ; i < ans.size(); ++i) {
cout << ans[i];
}
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

C. Divide by Three DP的更多相关文章

  1. HDU 4301 Divide Chocolate (DP + 递推)

    Divide Chocolate Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  2. CodeForces - 792C Divide by Three (DP做法)

    C. Divide by Three time limit per test: 1 second memory limit per test: 256 megabytes input: standar ...

  3. Educational Codeforces Round 18 C. Divide by Three DP

    C. Divide by Three   A positive integer number n is written on a blackboard. It consists of not more ...

  4. HDU 4301 Divide Chocolate(DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=4301 题意: 有一块n*2大小的巧克力,现在某人要将这巧克力分成k个部分,每个部分大小随意,问有多少种分法. 思 ...

  5. XVII Open Cup named after E.V. Pankratiev. GP of SPb

    A. Array Factory 将下标按前缀和排序,然后双指针,维护最大的右边界即可. #include<cstdio> #include<algorithm> using ...

  6. UOJ276 [清华集训2016] 汽水 【二分答案】【点分治】【树状数组】

    题目分析: 这种乱七八糟的题目一看就是点分治,答案有单调性,所以还可以二分答案. 我们每次二分的时候考虑答案会不会大于等于某个值,注意到系数$k$是无意义的,因为我们可以通过转化使得$k=0$. 合并 ...

  7. LOJ6502. 「雅礼集训 2018 Day4」Divide(构造+dp)

    题目链接 https://loj.ac/problem/6502 题解 中间一档部分分提示我们将所有的 \(w_i\) 排序. 考虑如果我们能构造出这样一个 \(w_i\) 的序列,使得该序列满足:对 ...

  8. 【概率dp】Divide by Zero 2017 and Codeforces Round #399 (Div. 1 + Div. 2, combined) D. Jon and Orbs

    直接暴力dp就行……f(i,j)表示前i天集齐j种类的可能性.不超过10000天就能满足要求. #include<cstdio> using namespace std; #define ...

  9. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

随机推荐

  1. 用mingw-w64 编译 x64 位的ffmpeg

    http://blog.sina.com.cn/s/blog_6125d067010168dt.html 工作中用到了ffmpeg x64. 发现编译出来x64的ffmpeg,很不容易.特记录下来.原 ...

  2. codeforces A. Nuts 解题报告

    题目链接:http://codeforces.com/problemset/problem/402/A 题目意思:几经辛苦,终于体明题目噶意思了 = =,完全是考验一个人是否清醒的最简便方法- -! ...

  3. dhclient命令

    语法:dhclient(选项)(参数) 选项0:指定dhcp客户但监听的端口号-d:总是以前台方式运行程序-q:安静模式,不打印任何错误的提示信息-r:释放ip地址 参数:网络接口:操作的网络接口 示 ...

  4. liunx目录/etc下相关配置

    这些都是比较有实用性的系统配置,收藏下,以备不时之需!以下是etc下重要配置文件解释: 1./etc/hosts  #文件格式: IPaddress hostname aliases #文件功能: 提 ...

  5. P4147玉蟾宫——最大子矩阵

    悬线法裸题. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace ...

  6. mysql跨表更新示例

    一.在同一个表中冗余存储记录之间的关系(组织机构树),查询时需要根据冗余字段进行关联查询 例如,下面的示例,用户表中有个字段friend标记其朋友关系,要求找出id=2及他的朋友(父节点) mysql ...

  7. epoll的一个使用例子

    使用到主要函数有: #include <sys/epoll.h> int epoll_create(int size); int epoll_create1(int flags); int ...

  8. PB调用C# Windows窗体

    以下是PB中的代码:String ls_filenameLong ll_wstyle=1long ll_hwnd,ll_nShowCmdstring ls_lpOperation,ls_lpFile, ...

  9. CF-799B

    B. T-shirt buying time limit per test 3 seconds memory limit per test 256 megabytes input standard i ...

  10. 国内互联网公司的开源项目及github地址汇总

    国内互联网公司的开源项目及github地址汇总 阿里 阿里的开源项目很多,这也跟@淘宝正明的开源态度密不可分.有很多重量级的项目,例如LVS.Tengine,或者很有实践价值的中间件,例如 MetaQ ...