题目链接:

http://codeforces.com/problemset/problem/214/B

Hometask

time limit per test:2 seconds
memory limit per test:256 megabytes
#### 问题描述
> Furik loves math lessons very much, so he doesn't attend them, unlike Rubik. But now Furik wants to get a good mark for math. For that Ms. Ivanova, his math teacher, gave him a new task. Furik solved the task immediately. Can you?
>
> You are given a set of digits, your task is to find the maximum integer that you can make from these digits. The made number must be divisible by 2, 3, 5 without a residue. It is permitted to use not all digits from the set, it is forbidden to use leading zeroes.
>
> Each digit is allowed to occur in the number the same number of times it occurs in the set.
#### 输入
> A single line contains a single integer n (1 ≤ n ≤ 100000) — the number of digits in the set. The second line contains n digits, the digits are separated by a single space.
#### 输出
> On a single line print the answer to the problem. If such number does not exist, then you should print -1.
#### 样例
>**sample input**
> 11
> 3 4 5 4 5 3 5 3 4 4 0
>
> **sample output**
> 5554443330

题意

给你一n个数x1,...,xn(0<=xi<=9)。挑出若干个拼在一起,使得它的值最大。

题解

题目相当于是求从n个数中挑出最多的数,它们的和能被3整除,并且它们中要有至少一个0,如果有多种方法挑出最多的数就优先选大的数挑。

可以用数位dp做:dp[i][j]表示考虑到第i个数,前缀和%3==j的方案数。

先对原序列排个序(为了转移的时候贪心挑最大的数),从左到右扫一遍dp,用pre[i][j]记录一下路径。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<algorithm>
using namespace std; const int maxn = 1e5 + 10;
typedef long long LL; string str;
int arr[maxn];
int dp[maxn][3], pre[maxn][3];
vector<int> ans;
int n, m; int main() {
int zero = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &arr[i]);
}
sort(arr, arr + n);
memset(dp, -1, sizeof(dp));
for (int i = 0; i<maxn; i++) dp[i][0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 0; j<3; j++) {
dp[i][j] = dp[i - 1][j];
pre[i][j] = j;
int ne = ((j - arr[i]) % 3 + 3) % 3;
if (dp[i - 1][ne] >= 0 && dp[i][j] <= dp[i - 1][ne] + 1) {
dp[i][j] = dp[i - 1][ne] + 1;
pre[i][j] = ne;
}
}
}
int p = 0;
for (int i = n; i >= 1; i--) {
int bef = pre[i][p];
if (dp[i - 1][bef] + 1 == dp[i][p]) ans.push_back(arr[i]);
p = bef;
}
sort(ans.begin(), ans.end());
if (ans[0] != 0) {
puts("-1");
return 0;
}
int i = ans.size() - 1;
for (; i>0 && ans[i] == 0; i--);
for (; i >= 0; i--) printf("%d", ans[i]);
puts("");
return 0;
}

Codeforces Round #131 (Div. 2) B. Hometask dp的更多相关文章

  1. Codeforces Round #131 (Div. 1) B. Numbers dp

    题目链接: http://codeforces.com/problemset/problem/213/B B. Numbers time limit per test 2 secondsmemory ...

  2. Codeforces Round #131 (Div. 2) E. Relay Race dp

    题目链接: http://codeforces.com/problemset/problem/214/E Relay Race time limit per test4 secondsmemory l ...

  3. Codeforces Round #131 (Div. 2)

    A. System of Equations \(a\)的范围在\(\sqrt n\)内,所以暴力枚举即可. B. Hometask 需要被2.5整除,所以末位必然为0,如果0没有出现,则直接返回-1 ...

  4. Codeforces Round #276 (Div. 1) D. Kindergarten dp

    D. Kindergarten Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/proble ...

  5. Codeforces Round #260 (Div. 1) A - Boredom DP

    A. Boredom Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/455/problem/A ...

  6. Codeforces Round #533 (Div. 2) C.思维dp D. 多源BFS

    题目链接:https://codeforces.com/contest/1105 C. Ayoub and Lost Array 题目大意:一个长度为n的数组,数组的元素都在[L,R]之间,并且数组全 ...

  7. Codeforces Round #539 (Div. 2) 异或 + dp

    https://codeforces.com/contest/1113/problem/C 题意 一个n个数字的数组a[],求有多少对l,r满足\(sum[l,mid]=sum[mid+1,r]\), ...

  8. Codeforces Round #374 (Div. 2) C. Journey DP

    C. Journey 题目连接: http://codeforces.com/contest/721/problem/C Description Recently Irina arrived to o ...

  9. Codeforces Round #202 (Div. 1) D. Turtles DP

    D. Turtles Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/547/problem/B ...

随机推荐

  1. POJ C++程序设计 编程题#1 大整数的加减乘除

    编程题#4:大整数的加减乘除 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 ...

  2. php异常处理示例

    php异常处理使用示例,代码说明了普通错误和致命错误捕获及处理的方法.  代码如下: <?php //禁止错误输出 error_reporting(0); //设置错误处理器 set_error ...

  3. ajax+php+mysql更新

    html代码 <input type="button" id="quxiao" class="quxiao" name="q ...

  4. DrawTool多重笔之前奏 => 通过InkAnalyzer实现图形识别

    这里要介绍的是通过InkAnalyzer来实现简单图形的识别,例如圆,椭圆,正方形,三角形等,当然你也可以通过扩展来实现自定义图形的识别,在使用InkAnalyzer前,你需要引用IAWinFX.dl ...

  5. C# 页面抓取获取快递信息

    通过页面抓取信息可以获得很多我们想要的信息,比如现在常会用到的快递查询,主要抓取的网站为http://www.kuaidi100.com/ 通过IE的网络分析我们可以得到下面信息 通过对这个网站的分析 ...

  6. linux安装R语言

    系统:centos 6.4  64bit 安装可以使用rpm包安装,也可以用源码安装. 但是rpm安装,各种依赖比较麻烦.所以我采用源码安装. 下载:http://www.r-project.org/ ...

  7. mysql开启日志

    在 centos 5 下,  在 mysld 下面,添加一行 log=/var/log/mysql.log 然后执行如下命令 touch /var/log/mysql.logchmod 777 /va ...

  8. iis7应用程序池自动关闭问题解决

    解决: 应用程序池启动32位应用程序 设置托管管道为集成 (仍然有问题) 图片:123.png 访问网站之前 应用程序池是开启的 访问后 网页报503 service unavailable应用程序池 ...

  9. Android HttpClient GET或者POST请求基本使用方法(转)

    在Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便我们使用各种Http服务.这里只介绍如何使用HttpCl ...

  10. Data Developer Center > Learn > Entity Framework > Get Started > Loading Related Entities

    Data Developer Center > Learn > Entity Framework > Get Started > Loading Related Entitie ...