Dynamic programming and sets/multisets

advertisement
ACM notes
• Sometimes a problem is much more difficult than expected!
strategize as a team to find an algorithm
• Basic approach:
implement (1 or 2 people coding)
debugging
Sigma problem
1
1
1
1
1
1
1
2
2
2
2
2
2
2
3
4
4
4
4
4
4
8
6
8
8
8
9
9 17 34 68 77
16 32 64 80
16 24 28 29 58 87
16 32 33 66 99
stated answers
1
1
1
1
1
1
1
2
2
2
2
2
2
2
3
4
4
4
4
3
3
8
5
8
6
6
9
9 18 36 72 77
16 32 64 80
12 24 48 72 84 87
12 24 48 96 99
better answers
Change
const int p=1,n=5,d=10,q=25,h=50;
int counter=0;
int pn, nn, dn, qn, hn;
for (hn = 0; hn*h <= num; hn++)
for (qn = 0; hn*h + qn*q <= num; qn++)
for (dn = 0; hn*h + qn*q + dn*d <= num; dn++)
for (nn = 0; hn*h + qn*q + dn*d + nn*n <= num; nn++)
for (pn = 0; hn*h + qn*q + dn*d + nn*n + pn*p <= num; pn++)
{
if (hn*h + qn*q + dn*d + nn*n + pn*p == num)
counter++;
}
Brute Force
Dynamic Programming
using
1¢
total
1¢, 5¢
1¢, 5¢, 10¢
0¢
1¢
2¢
3¢
4¢
5¢
6¢
7¢
8¢
9¢ 10¢
11¢ 12¢
Change
const int p=1,n=5,d=10,q=25,h=50;
int counter=0;
int pn, nn, dn, qn, hn;
for (hn = 0; hn*h <= num; hn++)
for (qn = 0; hn*h + qn*q <= num; qn++)
for (dn = 0; hn*h + qn*q + dn*d <= num; dn++)
for (nn = 0; hn*h + qn*q + dn*d + nn*n <= num; nn++)
for (pn = 0; hn*h + qn*q + dn*d + nn*n + pn*p <= num; pn++)
{
if (hn*h + qn*q + dn*d + nn*n + pn*p == num)
counter++;
}
Brute Force
Dynamic Programming
0¢
1¢
2¢
3¢
4¢
5¢
6¢
7¢
8¢
1
1
1
1
1
1
1
1
1
1
1¢, 5¢
1
1
1
1
1
2
2
2
2
2
1¢, 5¢, 10¢
1
1
1
1
1
2
2
2
2
2
using
1¢
total
9¢ 10¢
1
11¢ 12¢
Change
const int p=1,n=5,d=10,q=25,h=50;
int counter=0;
int pn, nn, dn, qn, hn;
for (hn = 0; hn*h <= num; hn++)
for (qn = 0; hn*h + qn*q <= num; qn++)
for (dn = 0; hn*h + qn*q + dn*d <= num; dn++)
for (nn = 0; hn*h + qn*q + dn*d + nn*n <= num; nn++)
for (pn = 0; hn*h + qn*q + dn*d + nn*n + pn*p <= num; pn++)
{
if (hn*h + qn*q + dn*d + nn*n + pn*p == num)
counter++;
}
Brute Force
Dynamic Programming
0¢
1¢
2¢
3¢
4¢
5¢
6¢
7¢
8¢
1
1
1
1
1
1
1
1
1
1
1
1¢, 5¢
1
1
1
1
1
2
2
2
2
2
add
1¢, 5¢, 10¢
1
1
1
1
1
2
2
2
2
2
using
1¢
total
9¢ 10¢
11¢ 12¢
Change
const int p=1,n=5,d=10,q=25,h=50;
int counter=0;
int pn, nn, dn, qn, hn;
for (hn = 0; hn*h <= num; hn++)
for (qn = 0; hn*h + qn*q <= num; qn++)
for (dn = 0; hn*h + qn*q + dn*d <= num; dn++)
for (nn = 0; hn*h + qn*q + dn*d + nn*n <= num; nn++)
for (pn = 0; hn*h + qn*q + dn*d + nn*n + pn*p <= num; pn++)
{
if (hn*h + qn*q + dn*d + nn*n + pn*p == num)
counter++;
}
Brute Force
Dynamic Programming
0¢
1¢
2¢
3¢
4¢
5¢
6¢
7¢
8¢
1
1
1
1
1
1
1
1
1
1
1
1
1
1¢, 5¢
1
1
1
1
1
2
2
2
2
2
3
3
3
1¢, 5¢, 10¢
1
1
1
1
1
2
2
2
2
2
4
4
4
using
1¢
total
9¢ 10¢
11¢ 12¢
Prime numbers
Check for divisibility by integers up to the square root of N.
Or, just count factors...
2
3
4
5
Bug of the week:
int* factorTable = new int[1000000];
6
7
Prime
suspects
8
9
10
#define MAXFAC 1000005
int fac[MAXFAC];
Problems
Entropy
bits used in ASCII
Input
Output
AAAAABCD
64 13 4.9
bits used in an optimal
“prefix-free” encoding
compression ratio, to
1 place of precision
Problems
Entropy
bits used in ASCII
Input
Output
AAAAABCD
64 13 4.9
bits used in an optimal
“prefix-free” encoding
A
B
0
10
C
D
110
111
compression ratio, to
1 place of precision
Problems
N-Credible Mazes
dimensions
2
Input
start
Output
end
Maze #1 can be travelled
0 0 2 2
(or not…)
edge
start
0 0 0 1
0 1 0 2
0 2 1 2
0 2 0 3
1 2 2 2
-1
edge
end
www.dinkumware.com/htm_cpl/index.html
set
#include <set>
C++ STL
www.sgi.com/tech/stl/
set<int> s;
// basically a bin. tree
s.size();
// returns an int
s.insert(14);
// adds 14
s.insert(-9);
// adds -9
s.insert(42);
// adds 42
set<int>::iterator i; // may want to typedef
// think of an iterator as a pointer
i = s.find(42);
multiset
#include <set>
// return 42’s iterator
cout << (*i) << endl; // prints 42
cout << (*--i));
// prints ...
i = s.find(43);
// not there !
// at this point ( i == s.end() ) is true
s.erase(-9);
// removing elements
multiset<int> m;
// holds multiple copies
Breadth-first search
• algorithm
data structures
queue, deque, hashtable (map)
www.dinkumware.com/htm_cpl/index.html
vector
#include <vector>
sort
#include <algorithm>
C++ STL
www.sgi.com/tech/stl/
vector<int> v;
// basically an int array
v.reserve(10);
// assure 10 spots
v.push_back(42);
// adds 42 to the end
v.back();
// returns 42
v.pop_back();
// removes 42
v.size();
// # of elements
v[i];
// ith element
sort( v.begin(), v.end() );
// default sort
sort( v.begin(), v.end(), mycompare );
last time
deque
#include <deque>
deque<int> d;
// double-ended queue
d.push_front(42);
// add to front
d.front(42);
// return front element
d.pop_front(42);
// remove from front
Other problems
• Change counting
input:
1.00
output:
0.06
There are 292 ways to make $1.00
There are 2 ways to make $0.06
0
• Sigma series
input:
3
output:
1 2 3
Shortest sequences from 1 to N
such that each element is the
sum of two previous elements.
4
1 2 4
87
1 2 4 8 16 24 28 29 58 87
99
1 2 4 8 16 32 33 66 99
-1
Useful C functions
int atoi(char* s);
converts C strings to ints
atoi(“100”) == 100
double atof(char* s);
converts C strings to doubles
atoi(“100.0”) == 100.0
int strcasecomp(char* s1, char* s2);
case-insensitive C string comparison
strcasecmp(“aCm”,“ACm”) == 0
long strtol(char* s, NULL, int base)
arbitrary conversion from a string in bases (2-36) to a long int
strtol(“Charlie”, NULL, 36) ==
2147483647L
use man for more...
sprintf
int sprintf(char* str, char* format, ...);
prints anything to the string str
char str[100];
sprintf(str,“%d”,42);
// str is “42”
sprintf(str,“%f”,42.0);
// str is “42.0”
flexible formatting:
sprintf(str,“%10d”,42);
// str is “
42”
right/left justify:
sprintf(str,“%-10d”,42);
// str is “42
”
Two ACM programming skills
A chance to “improve” your C/C++ …
Preparation for the ACM competition ...
Problem Insight and Execution ...
1
Get into the minds
of the judges
2
Anxiety!
Key Skill #1:
mindreading
Get into the minds
of the judges
100%
0%
“What cases should I handle?” spectrum
Key Skill #2:
Anxiety!
anxiety
Dynamic Programming
Strategy: create a table of partial results & build on it.
divis.cc
T(n) = number of steps yet to go
T(n) = T(3n+1) + 1 if n odd
T(n) = T(n/2) + 1
if n even
Dynamic Programming
Keys: create a table of partial results, articulate
what each table cell means, then build it up...
i = possible remainder
Table T
0
divis.cc
j = items considered so far
0
1
2
3
4
5
6
1 1 6 2 -3
the list
1
2
4
the divisor
3
T[i][j] is 1 if i is a possible remainder using the first j items in the list.
Dynamic programs can be short
#include <cstdio>
#include <iostream>
#include <vector>
vector<int> v(10000);
vector<bool> m(100); // old mods
vector<bool> m2(100); // new mods
int n, k;
int main()
{
cin >> n;
// garbage
while (cin >> n) {
cin >> k;
bool divisible()
{
fill(m.begin(),m.end(),false);
m[0] = true;
for (int i=0; i<n; i++) {
cin >> v[i];
v[i] = abs(v[i]);
v[i] %= k;
}
for (int i=0; i<n; i++) {
cout << (divisible() ? "D" : "Not d")
<< "ivisible\n";
/* not giving away all of the code */
/* here the table is built (6 lines) */
}
return m[0];
}
cout << endl;
}
acknowledgment: Matt Brubeck
}
STL: http://www.sgi.com/Technology/STL
General ACM Programming
Try brute force first (or at least consider it)
-- sometimes it will work fine…
-- sometimes it will take a _bit_ too long
-- sometimes it will take _way_ too long
Best bugs from last week:
getting the input in the “pea” problem:
for (int j=1 ; j<N ; ++j)
{
cin >> Array[i];
}
filling in the table in the “divis” problem:
Table[i + n % k] = 1;
Table[i - n % k] = 1;
New Problem
Word Chains
Input A list of words
hertz
doze
jazz
aplomb
hajj
ceded
zeroth
dozen
envy
ballistic
yearn
Output yes or no -- can these words be chained together such
that the last letter of one is the first letter of the next… ?
Knapsack Problem
Maximize loot w/ weight limit of 4.
Number of
objects
considered
w
Weight available for use
0
1
2
3
n 4
V(n,w) =
1
2
object wt. val.
1
3
8
2
2
5
3
1
1
4
2
5
3
4
V(n,w) = max value stealable w/
‘n’ objects & ‘w’ weight
C Output
printf, fprintf, sprintf(char* s, const char* format, …)
the destination
the format string
the values
possible format strings
% -#0
.4 h d
12
minimum
field width
type
size
modifier
precision
flags
start character
0
+
(space)
#
d
u
o
x
f
e
g
c
s
n
%
left-justify
pad w/ zeros
use sign (+ or -)
use sign ( or -)
deviant operation
decimal integers
unsigned (decimal) ints
octal integers
hexadecimal integers
doubles (floats are cast)
doubles (exp. notation)
f or e, if exp < -3 or -4
character
string
outputs # of chars written !!
two of these print a ‘%’
allowed size modifiers
h
l
L
short
long (lowercase L)
long double
C Output
value = 42
%10.4d
%-#12x
value = -42
0042
0x2a
-0042
0xffffffd6
%+10.4g
value = 42
+42
value = -42.419
-42.42
%- 10.4g
42
-42.42
%-#10.4g
42.00
-42.42
value = “forty-two”
%10.5s
forty
Download