How is this DP solution approached? - c++

I have been trying to solve this TopCoder problem since a while now, and I'm not able to come up with a DP-based solution to this problem (given below). I also found a solution(also given below) by someone else to the problem, but I can't even understand it.
Could anyone help me with the solution here? I don't understand what line of thought would lead to this solution? How do I go about establishing the recurrence relation in my mind? I have absolutely no clue how to approach this problem, or how the person who wrote that solution wrote it.
PS: I'm aware TopCoder has editorials for problems, but this one's hasn't been released. I don't know why.
Here's the problem
Fox Ciel has lots of homework to do. The homework consists of some
mutually independent tasks. Different tasks may take different amounts
of time to complete. You are given a int[] workCost. For each i, the
i-th task takes workCost[i] seconds to complete. She would like to
attend a party and meet her friends, thus she wants to finish all
tasks as quickly as possible.
The main problem is that all foxes, including Ciel, really hate doing
homework. Each fox is only willing to do one of the tasks. Luckily,
Doraemon, a robotic cat from the 22nd century, gave Fox Ciel a split
hammer: a magic gadget which can split any fox into two foxes.
You are given an int splitCost. Using the split hammer on a fox is
instantaneous. Once a hammer is used on a fox, the fox starts to
split. After splitCost seconds she will turn into two foxes -- the
original fox and another completely new fox. While a fox is splitting,
it is not allowed to use the hammer on her again.
The work on a task cannot be interrupted: once a fox starts working on
a task, she must finish it. It is not allowed for multiple foxes to
cooperate on the same task. A fox cannot work on a task while she is
being split using the hammer. It is possible to split the same fox
multiple times. It is possible to split a fox both before and after
she solves one of the tasks.
Compute and return the smallest amount of time in which the foxes can
solve all the tasks.
Here's the solution:
1:
2: const int maxN = 55;
3: int dp[maxN][maxN*2];
4: int N;
5: int splitC;
6: vector<int> workC;
7:
8: int rec(int,int);
9: int FoxAndDoraemon::minTime(vector <int> workCost, int splitCost) {
10:
11: sort(workCost.begin(), workCost.end());
12: N = workCost.size();
13: splitC = splitCost;
14: workC = workCost;
15: memset(dp, -1, sizeof(dp));
16:
17: return rec(N-1, 1);
18: }
19:
20: int rec(int jobs, int fox)
21: {
22: if(jobs == -1) return 0;
23:
24: int& val = dp[jobs][fox];
25: if(val != -1) return val;
26: val = 0;
27:
28: if( (jobs+1) <= fox) val = max(workC[jobs] , rec(jobs-1, fox-1));
29: else
30: {
31: //split fox
32: val = splitC + rec(jobs, fox + 1);
33:
34: if( !(fox == 1 && jobs > 0) )
35: val = min(val, max(workC[jobs], rec(jobs-1, fox-1)));
36: }
37: return val;
38: }
39:

DP problems usually requires you to work out couple of examples and the only way to get good at it is to practice. Try solving some standard problem types in DP like longest increasing subsequence, knapsack, coins change, matrix multiplication, TSP etc. Try varients of these type.
As for the above problem, few things to note:
You need N foxes to finish N tasks (1 fox will work on only 1 task). So, if you've already cloned N foxes you don't need to create anymore. And, if you have more than 1 task, you have to split the first fox.
With each fox you can do two things
Split it and then calculate the minimum time taken
Don't split, but perform the current task and calculate the time it takes to perform remaining tasks with one less fox.
Note that you can only opt for not spliting if you have more than 1 Fox (or 1 Fox with 1 task).
This should give you an idea for the problem. I haven't thoroughly analyzed the problem, but the recursion doesn't seem to create overlapping calls i.e. if I have 3 tasks and 2 foxes, I'm only calling that state once and no more. So, the solution is a regular recursive solution and not a DP.

The editorial is now up at the TopCoder site.You can have a look there!

Related

Assign the work for 2 people so that the time is minimum

Question:
There are N works that needs to be assigned for 2 people. Person A can finish work i in a[i] time, person B can finish work i in b[i] time.
Each work can only be assigned to 1 person. After the works are assigned, each person will do their works seperately.
The overall time will be the larger of the total time taken by the 2 people.
Find a way to assign the work so that the Overall Time is minimum.
Example:
N = 6
a[] = 10 100 30 50 50 80
b[] = 100 30 40 40 60 90
Answer: 130
Explaination:
Person A do work 1, 3, 6 -> total time: 120
Person B do work 2, 4, 5 -> total time: 130
Overall time: 130
Constrants:
N <= 100
a[i], b[i] <= 30.000
My take
I tried solving it with dynamic-programming, more specifically: DP[i][p][c]
With i is the number of works done so far, p is total time of person A so far, c is total time of person B so far. For each i, we can try to give the work to either person A or B, then save the best answer in DP[i][p][c] so we dont have to recalculate it.
But p and c can get up to 3.000.000, so I tried to shrink it to DP[i][max(p,c)]
The code below gives the right answer for the example case, and some other case I generated:
int n, firstCost[105], secondCost[105];
int dp[105][300005];
int solve(int i, int p, int c){
if(i > n) return max(p, c);
int &res = dp[i][max(p, c)];
if(res != -1) return res;
res = INT_MAX;
int tmp1 = solve(i+1, p + firstCost[i], c);
int tmp2 = solve(i+1, p, c + secondCost[i]);
res = min(tmp1, tmp2);
return res;
}
int main(){
// input...
cout << solve(1, 0, 0);
}
But when I submited it, it gives the wrong anwer to this case:
20
4034 18449 10427 4752 8197 7698 17402 16164 12306 5249 19076 18560 16584 18969 3548 11260 6752 18052 14684 18113
19685 10028 938 10379 11583 10383 7175 4557 850 5704 14156 18587 2869 16300 15393 14874 18859 9232 6057 3562
My output was 77759 but the answer is suppose to be 80477.
I don't know what I did wrong, is there anyway to imrpove my solution?
P/S:
Here's the original problem, the page is in Vietnamese, you can create an account and submit there
The trick that you're missing is the idea of an optimal fringe.
You are trying to shrink it to max(p,c), but it may well be that you need to send the first half the jobs to person A, and that initially looks like a terrible set of choices. You are right that you could get the right answer with DP[i][p][c], but that quickly gets to be too much data.
But suppose that p0 <= p1 and c0 <= c1. Then there is absolutely no way that looking at a path through (p1, c1) can ever lead to a better answer than (p0, c0). And therefore we can drop (p1, c1) immediately.
I won't give you code, but I'll show you a bit of how this starts with your example.
4034 18449 10427 4752 8197 7698 17402 16164 12306 5249 19076 18560 16584 18969 3548 11260 6752 18052 14684 18113
19685 10028 938 10379 11583 10383 7175 4557 850 5704 14156 18587 2869 16300 15393 14874 18859 9232 6057 3562
At first we start off with DP = [[0,0]].
After we assign the first element, you get [[0,19685], [4034,0]].
After we assign the second we get, [[0,29713], [4034,10028], [18449,19685], [22483,0]]. We can drop [18449,19685] because it isn't as good as [4034,10028], so we get to [[0,29713], [4034,10028], [22483,0]].
The third element gives [[0,30651], [4034,10966], [10427,29713], [14461,10028], [22483,938], [32910,0]] and then we can drop [10427,29713] as being worse than [4034,10966]. And now we are at [[0,30651], [4034,10966], [14461,10028], [22483,938], [32910,0]].
And so on.
As an additional optimization I'd first sort the indexes by c[i]/p[i] and produce a greedy solution where we assign all of the beginning indexes to A and all of the end to B. From the existence of that greedy solution, we never need to look at any solution with p or c worse than that known solution. After we get half-way through the jobs, this should become a useful filter.

Why do atomic groups and non-capturing seem to add many steps [duplicate]

I was testing two almost identical regexes against a string (on regex101.com), and I noticed that there was a huge difference in the number of steps that they were taking. Here are the two regexes:
(Stake: £)(\d+(?:\.\d+)?)
(winnings: £)(\d+(?:\.\d+)?)
This is the string I was running them against (with modifiers g, i, m, u):
Start Game, Credit: £200.00game num: 1, Stake: £2.00Spinning Reels:NINE SEVEN KINGKING STAR ACEQUEEN JACK KINGtotal winnings: £0.00End Game, Credit: £198Start...
side note: the string/regexes are not mine, I just took them from elsewhere on SE and saw this behavior happening. It's not relevant to this question, but I figured it needed attribution.
(Note: Regex101 seems to be backed by PHP's PCRE regexes. The "optimizations off" setting is probably PCRE_NO_START_OPTIMIZE | PCRE_NO_AUTO_POSSESS. Thanks to Lucas Trzesniewski for figuring this out and writing some C# code to test it with.)
With optimizations on: the first one takes 304 steps to match, while the second one takes 21 steps. This is the huge discrepancy I am wondering about.
With optimizations off: the first one takes 333 steps to match, while the second one takes 317 steps. This would indicate that the first pattern is failing to be optimized, but not the second one.
Interestingly enough, without the u modifier, the first pattern (with optimizations on) only takes 40 steps. (But it doesn't change the performance of anything else, nor what the regex eventually matches.)
I'd like to know what in regex101's optimization engine (PCRE) is causing this discrepancy in the amount of steps. I am specifically looking for the reason that the longer regex takes less steps when unicode is enabled.
Is there a reason why this is happening or is this a bug in the engine?
Regex101 uses the PCRE library (by default), so its debugger is tied to PCRE's behavior. The PCRE library supports an auto-callout option through its PCRE_AUTO_CALLOUT flag, which invokes a callback function at every step of matching. I'm 99.99% sure that's how regex101's debugger works. Each callout invocation registers as a step in the debugger.
Testing with regex101
Now, take a look at the different steps involved, first, without the u option:
Notice how the text cursor jumps from the Start Game part directly to the Stake part.
What happens when you add u?
Notice the jump doesn't occur anymore, and this is where the additional steps come from.
What does the u option do? It sets PCRE_UTF8 | PCRE_UCP - yes, both of those at once, and this PCRE_UCP flag is important here.
Here's what the pcreunicode docs say:
Case-insensitive matching applies only to characters whose values are less than 128, unless PCRE is built with Unicode property support. A few Unicode characters such as Greek sigma have more than two codepoints that are case-equivalent. Up to and including PCRE release 8.31, only one-to-one case mappings were supported, but later releases (with Unicode property support) do treat as case-equivalent all versions of characters such as Greek sigma.
Because of the additional complexity in handling case insensitivity in Unicode mode, the engine cannot just skip all of the text. To verify this is the culprit, let's try this with the gmu flags (that is, with u but without i):
The optimization is applied even with u, and this pretty much confirms the hypothesis.
Observations
The slow path you're seeing looks just like if PCRE_NO_START_OPTIMIZE had been used (and this is probably part of what regex101's disable internal engine optimizations does, along with PCRE_NO_AUTO_POSSESS, which is not relevant here).
More about it from the docs:
There are a number of optimizations that pcre_exec() uses at the start of a match, in order to speed up the process. For example, if it is known that an unanchored match must start with a specific character, it searches the subject for that character, and fails immediately if it cannot find it, without actually running the main matching function.
For some reason (which will become apparent later), PCRE fails to register an s or k letter as a required starting character, and cannot use the anchoring optimization. All the other letters of the latin alphabet work just fine in this regard.
This is why Stake requires more steps than winnings: the engine just doesn't skip the checks.
Testing with PCRE directly
Here's a test program I used with PCRE 8.38, which is the latest PCRE1 version available as of this post.
#include <stdio.h>
#include <string.h>
#include <pcre.h>
static int calloutCount;
static int callout_handler(pcre_callout_block *c) {
++calloutCount;
return 0;
}
static void test_run(const char* pattern, pcre* re, pcre_extra* extra) {
int rc, startOffset;
int ovector[3 * 3];
pcre_callout = callout_handler;
calloutCount = 0;
startOffset = 0;
const char *subject = "Start Game, Credit: £200.00game num: 1, Stake: £2.00Spinning Reels:NINE SEVEN KINGKING STAR ACEQUEEN JACK KINGtotal winnings: £0.00End Game, Credit: £198Start...";
for (;;) {
rc = pcre_exec(re, extra, subject, strlen(subject), startOffset, 0, ovector, sizeof(ovector) / sizeof(int));
if (rc < 0)
break;
startOffset = ovector[1];
}
printf("%-30s %s => %i\n", pattern, extra ? "(studied) " : "(not studied)", calloutCount);
}
static void test(const char* pattern) {
pcre *re;
const char *error;
int erroffset;
pcre_extra *extra;
re = pcre_compile(pattern, PCRE_AUTO_CALLOUT | PCRE_CASELESS | PCRE_MULTILINE | PCRE_UTF8 | PCRE_UCP, &error, &erroffset, 0);
if (re == 0)
return;
extra = pcre_study(re, 0, &error);
test_run(pattern, re, extra);
if (extra)
test_run(pattern, re, NULL);
pcre_free_study(extra);
pcre_free(re);
}
int main(int argc, char **argv) {
printf("PCRE version: %s\n\n", pcre_version());
test("(Stake: £)(\\d+(?:\\.\\d+)?)");
test("(winnings: £)(\\d+(?:\\.\\d+)?)");
return 0;
}
The output I got is the following:
PCRE version: 8.38 2015-11-23
(Stake: £)(\d+(?:\.\d+)?) (studied) => 40
(Stake: £)(\d+(?:\.\d+)?) (not studied) => 302
(winnings: £)(\d+(?:\.\d+)?) (studied) => 21
(winnings: £)(\d+(?:\.\d+)?) (not studied) => 21
Here, we can see that studying the pattern makes a difference in the first case, but not in the second one.
Studying a pattern means the following:
Studying a pattern does two things: first, a lower bound for the length of subject string that is needed to match the pattern is computed. This does not mean that there are any strings of that length that match, but it does guarantee that no shorter strings match. The value is used to avoid wasting time by trying to match strings that are shorter than the lower bound. You can find out the value in a calling program via the pcre_fullinfo() function.
Studying a pattern is also useful for non-anchored patterns that do not have a single fixed starting character. A bitmap of possible starting bytes is created. This speeds up finding a position in the subject at which to start matching. (In 16-bit mode, the bitmap is used for 16-bit values less than 256. In 32-bit mode, the bitmap is used for 32-bit values less than 256.)
From the results and the docs description, you can conclude that PCRE considers the S character is not an anchoring character, and in caseless Unicode mode, it requires a bitmap to be created. The bitmap allows the optimization to be applied.
Now, here's the PCRE2 version, compiled against PCRE2 v10.21, which is the latest release as of this post. The results will be unsurprising as PCRE2 always studies the patterns you supply it, no questions asked.
#include <stdio.h>
#include <string.h>
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
static int callout_handler(pcre2_callout_block *c, void *data) {
++*((int*)data);
return 0;
}
static void test(const char* pattern) {
pcre2_code *re;
int error;
PCRE2_SIZE erroffset;
pcre2_match_context *match_context;
pcre2_match_data *match_data;
int rc, startOffset = 0;
int calloutCount = 0;
PCRE2_SIZE *ovector;
const PCRE2_SPTR subject = (PCRE2_SPTR)"Start Game, Credit: £200.00game num: 1, Stake: £2.00Spinning Reels:NINE SEVEN KINGKING STAR ACEQUEEN JACK KINGtotal winnings: £0.00End Game, Credit: £198Start...";
re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, PCRE2_AUTO_CALLOUT | PCRE2_CASELESS | PCRE2_MULTILINE | PCRE2_UTF | PCRE2_UCP, &error, &erroffset, 0);
if (re == 0)
return;
match_context = pcre2_match_context_create(0);
pcre2_set_callout(match_context, callout_handler, &calloutCount);
match_data = pcre2_match_data_create_from_pattern(re, 0);
ovector = pcre2_get_ovector_pointer(match_data);
for (;;) {
rc = pcre2_match(re, subject, PCRE2_ZERO_TERMINATED, startOffset, 0, match_data, match_context);
if (rc < 0)
break;
startOffset = ovector[1];
}
printf("%-30s => %i\n", pattern, calloutCount);
pcre2_match_context_free(match_context);
pcre2_match_data_free(match_data);
pcre2_code_free(re);
}
int main(int argc, char **argv) {
char version[256];
pcre2_config(PCRE2_CONFIG_VERSION, &version);
printf("PCRE version: %s\n\n", version);
test("(Stake: £)(\\d+(?:\\.\\d+)?)");
test("(winnings: £)(\\d+(?:\\.\\d+)?)");
return 0;
}
And here's the result:
PCRE version: 10.21 2016-01-12
(Stake: £)(\d+(?:\.\d+)?) => 40
(winnings: £)(\d+(?:\.\d+)?) => 21
Yup. Same results as in PCRE1 when studying was used.
Implementation details
Let's take a look at the implementation details, shall we? PCRE compiles a pattern to opcodes, which we can read with the pcretest program.
Here's the input file:
/(Stake: £)(\d+(?:\.\d+)?)/iDW8
Start Game, Credit: £200.00game num: 1, Stake: £2.00Spinning Reels:NINE SEVEN KINGKING STAR ACEQUEEN JACK KINGtotal winnings: £0.00End Game, Credit: £198Start...
/(winnings: £)(\d+(?:\.\d+)?)/iDW8
Start Game, Credit: £200.00game num: 1, Stake: £2.00Spinning Reels:NINE SEVEN KINGKING STAR ACEQUEEN JACK KINGtotal winnings: £0.00End Game, Credit: £198Start...
Its format is simple: A pattern in delimiters followed by options, and one or more input strings.
The options are:
i - PCRE_CASELESS
D - turn on debug mode: show the opcodes and pattern information
W - PCRE_UCP
8 - PCRE_UTF8
And the result is...
PCRE version 8.38 2015-11-23
/(Stake: £)(\d+(?:\.\d+)?)/iDW8
------------------------------------------------------------------
0 55 Bra
3 24 CBra 1
8 clist 0053 0073 017f
11 /i ta
15 clist 004b 006b 212a
18 /i e: \x{a3}
27 24 Ket
30 22 CBra 2
35 prop Nd ++
39 Brazero
40 9 Bra
43 /i .
45 prop Nd ++
49 9 Ket
52 22 Ket
55 55 Ket
58 End
------------------------------------------------------------------
Capturing subpattern count = 2
Options: caseless utf ucp
No first char
Need char = ' '
Start Game, Credit: £200.00game num: 1, Stake: £2.00Spinning Reels:NINE SEVEN KINGKING STAR ACEQUEEN JACK KINGtotal winnings: £0.00End Game, Credit: £198Start...
0: Stake: \x{a3}2.00
1: Stake: \x{a3}
2: 2.00
/(winnings: £)(\d+(?:\.\d+)?)/iDW8
------------------------------------------------------------------
0 60 Bra
3 29 CBra 1
8 /i winning
22 clist 0053 0073 017f
25 /i : \x{a3}
32 29 Ket
35 22 CBra 2
40 prop Nd ++
44 Brazero
45 9 Bra
48 /i .
50 prop Nd ++
54 9 Ket
57 22 Ket
60 60 Ket
63 End
------------------------------------------------------------------
Capturing subpattern count = 2
Options: caseless utf ucp
First char = 'w' (caseless)
Need char = ' '
Start Game, Credit: £200.00game num: 1, Stake: £2.00Spinning Reels:NINE SEVEN KINGKING STAR ACEQUEEN JACK KINGtotal winnings: £0.00End Game, Credit: £198Start...
0: winnings: \x{a3}0.00
1: winnings: \x{a3}
2: 0.00
Now this gets interesting!
First, we see the first pattern gets No first char, while the second one gets First char = 'w' (caseless).
The S is identified as: clist 0053 0073 017f, while the k is turned into clist 004b 006b 212a. Those are the sets of matching codepoints for these letters. What do they represent?
S: 0053 = S, 0073 = s, 017f = ſ (Latin Small Letter Long S) - Yikes.
k: 004b = K, 006b = k, 212a = K (Kelvin Sign) - Double yikes.
The optimization is not applied because case folding for these two letters include characters outside the ASCII range.
Now you see :)
The solution for PHP
So, what can you do from PHP? You add the S modifier:
When a pattern is going to be used several times, it is worth spending more time analyzing it in order to speed up the time taken for matching. If this modifier is set, then this extra analysis is performed. At present, studying a pattern is useful only for non-anchored patterns that do not have a single fixed starting character.
Regex101 doesn't support pattern studying AFAIK.
As Lucas Trzesniewski pointed out, this behavior only happens with 2 letters within a-z: k and s. Which both occur in the first pattern, coincidentally.
I was wondering why I didn't see any improvement when I shortened the regex to (ke: £)(\d+(?:\.\d+)?), and that was why.
But I think I found the answer. I began digging through the PCRE source code, picking random files that seemed like they might be of interest. And I found pcre2_udc.c:
The tables herein are needed only when UCP support is built, and in PCRE2 that happens automatically with UTF support.
A little further down the page, I found this list of unicode points. I have put the corresponding Unicode character next to its hexadecimal value for quick reference:
const uint32_t PRIV(ucd_caseless_sets)[] = {
NOTACHAR,
0x0053, S 0x0073, s 0x017f, ſ NOTACHAR,
0x01c4, DŽ 0x01c5, Dž 0x01c6, dž NOTACHAR,
0x01c7, LJ 0x01c8, Lj 0x01c9, lj NOTACHAR,
0x01ca, NJ 0x01cb, Nj 0x01cc, nj NOTACHAR,
0x01f1, DZ 0x01f2, Dz 0x01f3, dz NOTACHAR,
0x0345, ͅ 0x0399, Ι 0x03b9, ι 0x1fbe, ι NOTACHAR,
0x00b5, µ 0x039c, Μ 0x03bc, μ NOTACHAR,
0x03a3, Σ 0x03c2, ς 0x03c3, σ NOTACHAR,
0x0392, Β 0x03b2, β 0x03d0, ϐ NOTACHAR,
0x0398, Θ 0x03b8, θ 0x03d1, ϑ 0x03f4, ϴ NOTACHAR,
0x03a6, Φ 0x03c6, φ 0x03d5, ϕ NOTACHAR,
0x03a0, Π 0x03c0, π 0x03d6, ϖ NOTACHAR,
0x039a, Κ 0x03ba, κ 0x03f0, ϰ NOTACHAR,
0x03a1, Ρ 0x03c1, ρ 0x03f1, ϱ NOTACHAR,
0x0395, Ε 0x03b5, ε 0x03f5, ϵ NOTACHAR,
0x1e60, Ṡ 0x1e61, ṡ 0x1e9b, ẛ NOTACHAR,
0x03a9, Ω 0x03c9, ω 0x2126, Ω NOTACHAR,
0x004b, K 0x006b, k 0x212a, K NOTACHAR,
0x00c5, Å 0x00e5, å 0x212b, Å NOTACHAR,
}
As a result, this regex:
(ſtake: £)(\d+(?:\.\d+)?)
is equivalent to my first regex.
Again, it was Lucas who put me on the right direction with the link to the the pcreunicode docs:
Case-insensitive matching applies only to characters whose values are less than 128, unless PCRE is built with Unicode property support. A few Unicode characters such as Greek sigma have more than two codepoints that are case-equivalent. Up to and including PCRE release 8.31, only one-to-one case mappings were supported, but later releases (with Unicode property support) do treat as case-equivalent all versions of characters such as Greek sigma.
The engine was failing to optimize things when any of these characters are present.
But looking within pcre2_study.c, I marked (with /**/) the line where the optimizations may happen during studying:
case OP_PROP:
if (tcode[1] != PT_CLIST) return SSB_FAIL;
{
const uint32_t *p = PRIV(ucd_caseless_sets) + tcode[2];
/**/ while ((c = *p++) < NOTACHAR)
{
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
if (utf)
{
PCRE2_UCHAR buff[6];
(void)PRIV(ord2utf)(c, buff);
c = buff[0];
}
#endif
if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);
}
}
try_next = FALSE;
break;

Safe mountaineers - task

I have to do homework and have been sitting for 4 hours. I don't know what to do next. The program compiles correctly but spits out the wrong data. He's not finished because I can't get through this problem. I'm just a beginner in c ++. Would anyone be able to help me?
Safe Mountaineers
A group of mountaineers climbs to the top following a narrow trail. Mountaineers are following one another carefully, because the path is steep and dangerous. Some of the climbers have a rope protection, and others unfortunately do not have it. The equipment of the group of mountaineers can be described using a series of letters:
• B means a safe climber (equipped with a rope);
• Z means mountaineer at risk (without rope).
For example, the string BZZBZ means a group of five mountaineers, two of whom have ropes. The group is headed by the first mountaineer on the right (in this case without a rope). Colleagues, however, are not left without help. A climber with a rope can pass the rope to a colleague walking directly in front of him (and then they are both safe), and this gesture is performed at once by all climbers who can do it. So in this case the string will change as follows:
BZZBZ- → BBZBB
Mountaineers who have become safe are marked in red. Such friendly gestures are repeated as long as possible:
BBZBB- → BBBBB
At this point, all mountaineers are safe - after two mate gestures. Of course, it will not be possible for every group of mountaineers to ensure safety for everyone. A mountaineer who walks at the beginning of the group cannot lend his rope to a friend because nobody walks in front of him.
Write a program that for a given group of mountaineers calculates the number of gestures needed to make everyone become safe, or declares that it is impossible.
Entrance
The first line of the standard input contains a positive integer denoting the number of data sets or groups of mountaineers (N≤200).
Each subsequent line contains a series of letters B or Z describing the equipment of mountaineers in a given group (according to the task). Each group has between 1 and 1,000,000 people, and it can be assumed that the total number of all groups will not exceed 20,000,000.
Exit
For each group, the program should write a line of text containing the number of gestures needed that will lead to a situation when all climbers in the group will become safe, or the number -1 if this is impossible.
Example
For the example input below:
3
BZZBBZ
Bzzz
ZBBB
the correct result is:
2
3
-1
Explanation of the example: The first case is described in the body of the task. In the second case, the rope feed proceeds as follows:
BZZZ- BBZZ- → → → BBBB BBBZ-
In the third case, the last climber cannot receive the rope.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int N, przejscia;
string a,b,c;
main()
{
N=3;
przejscia=0;
cout << N<<endl;
a="BZZBB\n";
char a1=(a[1]);
b="ZBBZBZBB\n";
c="BBZZZZBZBZBZ\n";
int ailosc = a.length();
int bilosc = b.length();
int cilosc = c.length();
cout <<a;
cout <<b;
cout <<c;
if (a[0]=='Z')
{cout << "-1";
}
if (b[0]=='Z')
{cout << "-1";
}
if (c[0]=='Z')
{cout << "-1";
}
int h, k;
h=0;
k=0;
if (a[0]=='B')
{for (int i=1; i<=ailosc; i++)
{h++;
if ((a[h]=='Z')and(a[k]=='B'))
{a[h]='B';
przejscia++;
}
k++;
}
}
cout << przejscia;
}

need help for codejam question "PARENTING PARTNERSHIP"

This question was asked on 4th april in google codejam : https://codingcompetitions.withgoogle.com/codejam/round/000000000019fd27/000000000020bdf9.
The description of question is :
Cameron and Jamie's kid is almost 3 years old! However, even though the child is more independent now, scheduling kid activities and domestic necessities is still a challenge for the couple.
Cameron and Jamie have a list of N activities to take care of during the day. Each activity happens during a specified interval during the day. They need to assign each activity to one of them, so that neither of them is responsible for two activities that overlap. An activity that ends at time t is not considered to overlap with another activity that starts at time t.
For example, suppose that Jamie and Cameron need to cover 3 activities: one running from 18:00 to 20:00, another from 19:00 to 21:00 and another from 22:00 to 23:00. One possibility would be for Jamie to cover the activity running from 19:00 to 21:00, with Cameron covering the other two. Another valid schedule would be for Cameron to cover the activity from 18:00 to 20:00 and Jamie to cover the other two. Notice that the first two activities overlap in the time between 19:00 and 20:00, so it is impossible to assign both of those activities to the same partner.
Given the starting and ending times of each activity, find any schedule that does not require the same person to cover overlapping activities, or say that it is impossible.
Input
The first line of the input gives the number of test cases, T. T test cases follow. Each test case starts with a line containing a single integer N, the number of activities to assign. Then, N more lines follow. The i-th of these lines (counting starting from 1) contains two integers Si and Ei. The i-th activity starts exactly Si minutes after midnight and ends exactly Ei minutes after midnight.
Output
For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is IMPOSSIBLE if there is no valid schedule according to the above rules, or a string of exactly N characters otherwise. The i-th character in y must be C if the i-th activity is assigned to Cameron in your proposed schedule, and J if it is assigned to Jamie.
If there are multiple solutions, you may output any one of them.
Input :
4
3
360 480
420 540
600 660
3
0 1440
1 3
2 4
5
99 150
1 100
100 301
2 5
150 250
2
0 720
720 1440
Output :
Case #1: CJC
Case #2: IMPOSSIBLE
Case #3: JCCJJ
Case #4: CC
My approach :
sort the task values on basis of starting or ending time and check whether it can be assigned to C or J. If all the task can be assigned then all good otherwise impossible.
I tried sorting on basis of both start time and end time but for both the cases got WA.
if someone can point out what i'm missing in implementation that qoulfd be very helpful.
My code:
#include<bits/stdc++.h>
using namespace std;
typedef struct task
{
int start_time;
int finish_time;
task()
{
this->start_time=0;
this->finish_time=0;
}
task(int start_time, int finish_time)
{
this->start_time=start_time;
this->finish_time=finish_time;
}
bool operator<(const task t)
{
return this->start_time<t.start_time;
}
}task;
int main()
{
int t;
cin>>t;
int a=1;
while(t--)
{
int n,st,ft;
cin>>n;
char res[1005];
int index = 0;
vector<task> task_list;
for(int i=0;i<n;i++)
{
cin>>st>>ft;
task t1(st,ft);
task_list.push_back(t1);
}
sort(task_list.begin(),task_list.end());
task j_task, c_task;
for(int i=0;i<n;i++)
{
if(task_list[i].start_time>=j_task.finish_time)
{
j_task = task_list[i];
res[index++] = 'J';
}
else if(task_list[i].start_time>=c_task.finish_time)
{
c_task = task_list[i];
res[index++] = 'C';
}
else
{
index = 0;
break;
}
}
if(index!=0)
{
res[index] = '\0';
cout<<"Case #"<<a++<<": "<<res<<endl;
}
else
{
cout<<"Case #"<<a++<<": "<<"IMPOSSIBLE"<<endl;
}
}
return 0;
}
You are asked to assign 'C' or 'J' to the original order of the tasks given in the input. So before sorting, you should save the index of the tasks and once sorted, assign 'C' or 'J' to those saved indices.

Is jBCrypt's default log_rounds still appropriate for 2013

I've been using jBCrypt version 0.3 out-of-the-box now since it came out in 2010. I use the default getsalt() method which sets the number of "log_rounds" to 10. Given the progression of password cracking hardware and methods, is this value still appropriate as a default, or should i be looking at some higher value.
Info from the javadoc...
String pw_hash = BCrypt_v03.hashpw(plain_password, BCrypt_v03.gensalt());
String strong_salt = BCrypt_v03.gensalt(10)
String stronger_salt = BCrypt_v03.gensalt(12)
The amount of work increases exponentially (2**log_rounds), so each increment is twice as much work. The default log_rounds is 10, and the valid range is 4 to 31.
I made a little test class to check the performance of checkPw() under differing salt log_rounds.
public void testCheckPerformance() {
int MULT = 1;
for( int i = 4; i < 31; i++) {
String salt = BCrypt_v03.gensalt(i);
String hashpw = BCrypt_v03.hashpw("my pwd", salt);
long startTs = System.currentTimeMillis();
for( int mult = 0; mult < MULT; mult++) {
assertTrue(BCrypt_v03.checkpw("my pwd", hashpw));
}
long endTs = System.currentTimeMillis();
System.out.println(""+i+": " + ((endTs-startTs)/MULT));
}
}
My PC is an 8 core i7 2.8GHz. The results are:
log-rounds: time in millis.
4: 3
5: 3
6: 6
7: 11
8: 22
9: 46
10: 92
11: 188
12: 349
13: 780
14: 1449
15: 2785
16: 5676
17: 11247
18: 22264
19: 45170
Using the default log_rounds=10 means that a single thread can check a login in 0.1s. This potentially limits the number of login checks per second that a single server can achieve.
So i guess the question becomes how much time are you prepared to spend per password check vs how many password checks per second you want to size the system to cope with.