听说30道dp可以入门??。。。。
1.poj-1015
http://poj.org/problem?id=1015
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#define N 201
#define M 21
using namespace std;
struct node {
int d;
int p;
int sum;
int dff;
}num[N];
int dp[N][M][801];
int re[N][M][801];
int main() {
int n, m;
int t = 1;
while (1) {
scanf("%d%d", &n, &m);
if (n == m && n == 0)
break;
for (int i = 1; i <= n; i++) {
scanf("%d%d", &num[i].p, &num[i].d);
num[i].sum = num[i].p + num[i].d;
num[i].dff = num[i].p - num[i].d;
}
int mid = 400;
memset(dp, -1, sizeof(dp));
memset(re, -1, sizeof(re));
for (int i = 0; i <= n; i++) {
dp[i][0][mid] = 0;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m && j <= i; j++) {
for (int k = 0; k <= mid*2; k++) {
dp[i][j][k] = dp[i - 1][j][k];
re[i][j][k] =re[i - 1][j][k];
if (k - num[i].dff >= 0 && dp[i - 1][j - 1][k - num[i].dff] != -1)
{
if (dp[i][j][k] < dp[i - 1][j - 1][k - num[i].dff] + num[i].sum)
{
dp[i][j][k] = dp[i - 1][j - 1][k - num[i].dff] + num[i].sum;
re[i][j][k] = i;
//cout << dp[i][j][k] <<" "<<i<<" "<<j<<" " <<k<<endl;
}
}
}
}
}
int sumd = 0, sump = 0;
int ans = 0;
int a[100];
for (int i = 0; i <= mid; i++) {
if (dp[n][m][mid - i] != -1 || dp[n][m][mid + i] != -1) {
if (dp[n][m][mid - i] > dp[n][m][mid + i]) {
int k = mid - i;
while (1) {
int ps = re[n][m][k];
//cout << ps << " " << n << " " << m << " " << k << endl;
a[ans++] = ps;
sump = sump + num[ps].p;
sumd = sumd + num[ps].d;
k = k - num[ps].dff; m--;
n = ps - 1;
if (m == 0)
break;
}
}
else {
int k = mid + i;
while (1) {
int ps = re[n][m][k];
//cout << ps <<" "<<n<<" "<<m<<" "<<k<< endl;
a[ans++] = ps;
sump = sump + num[ps].p;
sumd = sumd + num[ps].d;
k = k - num[ps].dff;m--;
n=ps-1;
if (m == 0)
break;
}
}
cout << "Jury #" << t++ << endl;
cout << "Best jury has value " << sump << " for prosecution and value " << sumd << " for defence:" << endl;
for (int i = ans-1; i >= 0; i--) {
cout << " " << a[i];
}
cout << endl;
break;
}
}
}
return 0;
}
2,poj-1035-DFS
http://poj.org/problem?id=1035
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
string DFS(string str) {
if (str=="01")
return str;
else
{
string strs = "";
vector<string> s;
int start = 0, end, cnt = 0;
str=str.substr(1, str.size() - 2);
//cout << str << endl;
for (int i = 0; i < str.length(); i++) {
if (str[i] == '0')
cnt++;
else
{
cnt--;
if (cnt == 0) {
end = i;
//cout << i << endl;
s.push_back(DFS(str.substr(start, end - start + 1)));
//cout << str.substr(start, end - start + 1);
start = i + 1;
}
}
}
sort(s.begin(), s.end());
strs += "0";
for (int i = 0; i < s.size(); i++) {
strs += s[i];
}
strs += "1";
return strs;
}
}
int main() {
int n;
scanf("%d", &n);
while (n--) {
string s1, s2;
cin >> s1 >> s2;
if (s1.length() != s2.length())
{
cout << "different" << endl;
continue;
}
s1 = "0" + s1 + "1";
s2 = "0" + s2 + "1";
//cout << "s" << endl;
s1 = DFS(s1);
s2 = DFS(s2);
if (s1 == s2)
cout << "same" << endl;
else
cout << "different" << endl;
}
return 0;
}
3,poj-1636
http://poj.org/problem?id=1636
DFS+DP解决
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#define N 205
using namespace std;
int t;
int n, m;
int anum, bnum;
int map[N][N];
int dp[N][N];
int vis[2][N];
void DFS(int side, int t) {
vis[side][t] = 1;
if (side == 0) {
anum++;
for (int i = 1; i <= n; i++) {
if (map[t][i] && !vis[1][i]) {
DFS(1, i);
}
}
}
else
{
bnum++;
for (int i = 1; i <= n; i++) {
if (map[i][t] && !vis[0][i]) {
DFS(0, i);
}
}
}
}
int main() {
scanf("%d", &t);
while (t--) {
memset(map, 0, sizeof(map));
memset(dp, 0, sizeof(dp));
memset(vis, 0, sizeof(vis));
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) {
int x, y;
scanf("%d%d", &x, &y);
map[x][y] = 1;
}
int a[N], b[N];
int k = 0;
for (int i = 1; i <= n; i++) {
if (vis[0][i])continue;
anum = 0;
bnum = 0;
DFS(0, i);
a[k] = anum;
b[k++] = bnum;
}
for (int i = 1; i <= n; i++) {
if (vis[1][i])continue;
anum = 0;
bnum = 0;
DFS(1, i);
a[k] = anum;
b[k++] = bnum;
}
dp[0][0] = 1;
for (int i = 0; i < k; i++) {
for (int j = n / 2; j >= a[i]; j--) {
for (int h = n / 2; h >= b[i]; h--) {
if (dp[j][h]||dp[j - a[i]][h - b[i]] == 1) {
dp[j][h] = 1;
}
}
}
}
for (int i = n / 2; i >= 0; i--) {
if (dp[i][i] == 1)
{
cout << i << endl;
break;
}
}
}
}
并查集+DP解决:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<set>p
#define N 205
using namespace std;
int t;
int p[2*N];
int find(int x) {
if (x != p[x]) {
p[x] = find(p[x]);
}
else
return x;
}
void build(int x, int y) {
int xx = find(x);
int yy = find(y);
if (xx != yy) {
p[xx] = yy;
}
}
void init(int n)
{
for (int i = 1; i <= 2 * n; i++) {
p[i] = i;
}
}
int main() {
int x, y, n, ks;
scanf("%d", &t);
while (t--) {
int a[N];
int b[N];
int sum[2 * N];
int dp[N / 2][N / 2];
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
memset(a, 0, sizeof(a));
memset(sum, 0, sizeof(sum));
memset(b, 0, sizeof(b));
scanf("%d%d", &n, &ks);
init(n);
for (int i = 0; i < ks; i++) {
scanf("%d%d", &x, &y);
build(x, y + n);
}
int ans = 1;
for (int i = 1; i <= n; i++)
{
int x = find(i);
if (sum[x] == 0) {
sum[x] = ans++;
a[sum[x]]++;
}
else
{
a[sum[x]]++;
}
}
for (int i = n + 1; i <= 2 * n; i++)
{
int x = find(i);
if (sum[x] == 0) {
sum[x] = ans++;
b[sum[x]]++;
}
else
{
b[sum[x]]++;
}
}
for (int i = 1; i < ans; i++) {
for (int j = n / 2; j >= a[i]; j--) {
for (int k = n / 2; k >= b[i]; k--) {
if (dp[j][k]||dp[j - a[i]][k - b[i]] == 1) {
dp[j][k] = 1;
}
}
}
}
for (int i = n / 2; i >= 0; i--) {
if (dp[i][i] == 1)
{
cout << i << endl;
break;
}
}
}
return 0;
}
4,poj-1671 DP 递归 第二类斯特林数(Stirling)
http://poj.org/problem?id=1671
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
#define N 105
double dp[N][N];
int main() {
int n;
while (~scanf("%d", &n) && n != 0) {
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++) {
dp[i][1] = 1;
}
dp[0][0] = 1;
double sum = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i][j] = dp[i - 1][j - 1] + j*dp[i - 1][j];
}
}
for (int i = 1; i <= n; i++) {
sum += dp[n][i];
}
printf("%d %.0f\n", n, sum);
}
return 0;
}
未完待续。。。。