## 【 题集 】 【kuangbin带你飞】专题十二 基础DP1

2019年02月19日 ⁄ 综合 ⁄ 共 10768字 ⁄ 字号 评论关闭

#### B - Ignatius and the Princess IV

Time Limit:1000MS     Memory Limit:32767KB     64bit IO Format:%I64d
& %I64

Description

"OK, you are not too bad, em... But you can never pass the next test." feng5166 says.

"I will tell you an odd number N, and then N integers. There will be a special integer among them, you have to tell me which integer is the special one after I tell you all the integers." feng5166 says.

"But what is the characteristic of the special integer?" Ignatius asks.

"The integer will appear at least (N+1)/2 times. If you can't find the right integer, I will kill the Princess, and you will be my dinner, too. Hahahaha....." feng5166 says.

Can you find the special integer for Ignatius?

Input

The input contains several test cases. Each test case contains two lines. The first line consists of an odd integer N(1<=N<=999999) which indicate the number of the integers feng5166 will tell our hero. The second line contains the
N integers. The input is terminated by the end of file.

Output

For each test case, you have to output only one line which contains the special number you have found.

Sample Input

``` 5
1 3 2 3 3
11
1 1 1 1 1 5 5 5 5 5 5
7
1 1 1 1 1 1 1 ```

Sample Output

``` 3
5
1 ```

```#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;

#define N 1000010

int n;
int tt[N];

int main()
{
int t;
while(~scanf("%d",&n))
{
memset(tt, 0, sizeof(tt));
int ans = 0;
for(int i = 0; i < n; i ++)
{
scanf("%d",&t);
tt[t] ++;
if(tt[t] >= (n + 1)/2)
ans = max(ans, t);
}
printf("%d\n", ans);
}
}```

#### E - Super Jumping! Jumping! Jumping!

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d
& %I64

Description

Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. Maybe you are a good boy, and know little about this game, so I introduce it to you now.

The game can be played by two or more than two players. It consists of a chessboard（棋盘）and some chessmen（棋子）, and all chessmen are marked by a positive integer or “start” or “end”. The player starts from start-point and must jumps into end-point finally. In
the course of jumping, the player will visit the chessmen in the path, but everyone must jumps from one chessman to another absolutely bigger (you can assume start-point is a minimum and end-point is a maximum.). And all players cannot go backwards. One jumping
can go from a chessman to next, also can go across many chessmen, and even you can straightly get to end-point from start-point. Of course you get zero point in this situation. A player is a winner if and only if he can get a bigger score according to his
jumping solution. Note that your score comes from the sum of value on the chessmen in you jumping path.
Your task is to output the maximum value according to the given chessmen list.

Input

Input contains multiple test cases. Each test case is described in a line as follow:
N value_1 value_2 …value_N
It is guarantied that N is not more than 1000 and all value_i are in the range of 32-int.
A test case starting with 0 terminates the input and this test case is not to be processed.

Output

For each case, print the maximum according to rules, and one line one case.

Sample Input

``` 3 1 3 2
4 1 2 3 4
4 3 3 2 1
0 ```

Sample Output

``` 4
10
3 ```
```#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;

#define N 1010

int tt[N];
int dp[N];

int main()
{
int n;
while(~scanf("%d",&n), n)
{
memset(dp, 0, sizeof(dp));

for(int i = 0; i < n; i ++)
{
scanf("%d",&tt[i]);
}

dp[0] = tt[0];
int ans = tt[0];

for(int i = 1; i < n; i ++)
{
dp[i] = tt[i];
for(int j = 0; j < i; j ++)
{
if(tt[j] < tt[i])
{
dp[i] = max(dp[i],dp[j] + tt[i]);
}
}
if(ans < dp[i])
ans = dp[i];
}
printf("%d\n", ans);
}
}```

#### F - Piggy-Bank

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d
& %I64

Description

Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. The main income for this action comes from Irreversibly Bound Money (IBM). The idea behind is simple. Whenever some ACM member has
any small money, he takes all the coins and throws them into a piggy-bank. You know that this process is irreversible, the coins cannot be removed without breaking the pig. After a sufficiently long time, there should be enough cash in the piggy-bank to pay
everything that needs to be paid.

But there is a big problem with piggy-banks. It is not possible to determine how much money is inside. So we might break the pig into pieces only to find out that there is not enough money. Clearly, we want to avoid this unpleasant situation. The only possibility
is to weigh the piggy-bank and try to guess how many coins are inside. Assume that we are able to determine the weight of the pig exactly and that we know the weights of all coins of a given currency. Then there is some minimum amount of money in the piggy-bank
that we can guarantee. Your task is to find out this worst case and determine the minimum amount of cash inside the piggy-bank. We need your help. No more prematurely broken pigs!

Input

The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing two integers E and F. They indicate the weight of an empty pig and of the pig filled
with coins. Both weights are given in grams. No pig will weigh more than 10 kg, that means 1 <= E <= F <= 10000. On the second line of each test case, there is an integer number N (1 <= N <= 500) that gives the number of various coins used in the given currency.
Following this are exactly N lines, each specifying one coin type. These lines contain two integers each, Pand W (1 <= P <= 50000, 1 <= W <=10000). P is the value of the coin in monetary units, W is it's weight in grams.

Output

Print exactly one line of output for each test case. The line must contain the sentence "The minimum amount of money in the piggy-bank is X." where X is the minimum amount of money that can be achieved using coins with the given total
weight. If the weight cannot be reached exactly, print a line "This is impossible.".

Sample Input

``` 3
10 110
2
1 1
30 50
10 110
2
1 1
50 30
1 6
2
10 3
20 4 ```

Sample Output

``` The minimum amount of money in the piggy-bank is 60.
The minimum amount of money in the piggy-bank is 100.
This is impossible.```

恰好装满的背包问题，最后判断一下就可以了

```#include <stdio.h>

const int N = 550;
int c[N];
int w[N];
int dp[10010];
const int INF = 10000000;

int min(int x, int y)
{
return x < y ? x : y ;
}

int main()
{
int n, m;
int i, j;
int a, b;
int cc, ww;
while(~scanf("%d",&n))
{
while(n --)
{
scanf("%d%d", &cc, &ww);
scanf("%d", &m);
for(i = 0; i <= ww - cc; i ++)
dp[i] = INF;
for(i = 0; i < m; i ++)
scanf("%d%d",&c[i], &w[i]);
dp[0] = 0;
for(i = 0;i < m; i ++)
{
for(j = w[i]; j <= ww - cc; j ++)
dp[j] = min(dp[j - w[i]] + c[i], dp[j]);
}
if(dp[ww - cc] == INF)
printf("This is impossible.\n");
else
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[ww - cc]);
}
}
return 0;
}```

G - 免费馅饼

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d
& %I64u

Description

Input

Output

Sample Input

``` 6
5 1
4 1
6 1
7 2
7 2
8 3
0 ```

Sample Output

` 4 `

可以把它转换成数塔问题，一开始我从上往下，绕了许久！在贪心的时候，也要注意范围！！！

```#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;

#define N 100010

int dp[N][12];

int main()
{
int n;
int a, t;
while(~scanf("%d",&n), n)
{
memset(dp, 0, sizeof(dp));

int maxt = 0;

for(int i = 1; i <= n; i ++)
{
scanf("%d%d",&a,&t);
maxt = max(maxt, t);
dp[t][a + 1] ++;
}
for(int i = maxt - 1; i >= 0; i --)
{
for(int j = 1; j <= 11; j ++)
{
dp[i][j] += max(dp[i + 1][j], max(dp[i + 1][j + 1], dp[i + 1][j -1]));
}
}
printf("%d\n", dp[0][6]);
}
return 0;
}```

#### I - 最少拦截系统

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d
& %I64u

Description

Input

Output

Sample Input

` 8 389 207 155 300 299 170 158 65 `

Sample Output

` 2 `

这道题想了很久，最后用贪心写的，网上有许多不同的解法，不知道是数据弱还是怎么回事。

用一个数组记录最大值，如果比它大，再取一个，到最后有几个，就是答案。

```#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;

#define N 120
#define Max 1 << 29

int tt[N];
int ans[N];

int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i = 1; i <= n; i ++)
{
scanf("%d",&tt[i]);
}

int tmp_1 = 1;
int cnt = 1;
ans[1] = tt[1];

for(int i = 2; i <= n; i ++)
{
bool flag = false;
for(int j = 1; j <= cnt; j ++)
{
if(ans[j] > tt[i])
{
ans[j] = tt[i];
flag = true;
break;
}
}
if(!flag)
{
ans[cnt + 1] = tt[i];
cnt ++;
//tmp_1 ++;
}
}
printf("%d\n", cnt);
}
}```

#### L - Common Subsequence

Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d
& %I64u

Description

A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, ..., xm > another sequence Z = < z1, z2, ..., zk > is a subsequence of X if there exists a strictly increasing sequence < i1,
i2, ..., ik > of indices of X such that for all j = 1,2,...,k, x ij = zj. For example, Z = < a, b, f, c > is a subsequence of X = < a, b, c, f, b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y the problem is to find
the length of the maximum-length common subsequence of X and Y.

Input

The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.

Output

For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.

Sample Input

```abcfbc         abfcab
programming    contest
abcd           mnp```

Sample Output

```4
2
0```

这题就是最长公共子序列了、

注意边界的问题！

```#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;

#define N 1001
#define Max 1 << 29

char str1[N];
char str2[N];
int dp[N][N];

int main()
{
while(~scanf("%s%s",str1 ,str2 ))
{
int len1 = strlen(str1);
int len2 = strlen(str2);
memset(dp, 0, sizeof(dp));

for(int i = 1; i <= len1; i ++)
{
for(int j = 1; j <= len2; j ++)
{
//dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

if(str1[i - 1] == str2[j - 1])
{
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}

/*for(int i = 0; i < len1; i ++)
{
for(int j = 0; j < len2 ; j ++)
{
printf("%d", dp[i][j]);
}
printf("\n");
}*/

printf("%d\n", dp[len1][len2]);
}
}

/******

abcfbc         abfcab
programming    contest
abcd           mnp
aaaaa a
aaa aaaaaa

************/```

#### N - Longest Ordered Subsequence

Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d
& %I64u

Description

A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence ( a1a2, ..., aN)
be any sequence (ai1ai2, ..., aiK), where 1 <= i1 < i2 < ... < iK <= N. For example, sequence
(1, 7, 3, 5, 9, 4, 8) has ordered subsequences, e. g., (1, 7), (3, 4, 8) and many others. All longest ordered subsequences are of length 4, e. g., (1, 3, 5, 8).

Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.

Input

The first line of input file contains the length of sequence N. The second line contains the elements of sequence - N integers in the range from 0 to 10000 each, separated by spaces. 1 <= N <= 1000

Output

Output file must contain a single integer - the length of the longest ordered subsequence of the given sequence.

Sample Input

```7
1 7 3 5 9 4 8```

Sample Output

`4`

最长上升序列

```#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;

#define N 1010

int tt[N];
int slen[N];

void init(int n)
{
for(int i = 1; i <= n; i ++)
{
slen[i] = 1;
}
}

int main()
{
int n;
while(~scanf("%d",&n))
{
init(n);
for(int i = 1; i <= n; i ++)
{
scanf("%d",&tt[i]);
}
int ans = 1;
for(int i = 2; i <= n; i ++)
{
int maxn = 0;
for(int j = 1; j <= i - 1; j ++)
{
if(tt[j] < tt[i] && slen[j] > maxn)
maxn = slen[j];
}
slen[i] = maxn + 1;
if(slen[i] > ans)
ans = slen[i];
}
printf("%d\n",ans);
}
}```