您的位置:首页 > 其它

CCNU 2010新生练习赛(DP)[差很多的解题报告]

2011-05-02 02:09 363 查看
话说这套题这么久了都没有搞定,喵呜大神说简单的都不屑于做的题,就是做不出来。。orz 膜拜喵呜大神。我现在的水平比喵呜去年这个时候差太多了,再次膜拜。

SSY同学很用心,望一起努力。其他同学也是啊。

只写做了的几个题吧。惭愧啊。

============================我是被人抛弃的昏割线============================

Max Sum

Problem Description
Given a sequence a[1],a[2],a[3]......a
, your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.

Input

The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).

Output

For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.

Sample Input

2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5


Sample Output

Case 1:
14 1 4

Case 2:
7 1 6


--------------------

话说这个题我做了一个寒假,最后寒假回来在某节高数课上才想出来oTZ,SSY同学一会儿就想出来了,膜拜一下。第一次做还用了指针,还用了C++库。。

其实DP这个东西应该是有阶段性的(不知道术语怎么说),比如数塔的一个阶段就是一层。阶段里包含多个状态,由当前状态和子状态找状态转移方程,这个方程才是DP的精髓吧。我这么理解的,不知道对不对。。

直接附代码了,这题C语言写的不堪入目,所以放了java写的这个,那个实在写的悲剧:

int C=cin.nextInt();
int T,n,maxsum,nowsum,i,now;
int[] A=new int[100005];
boolean flag=false;
for(T=1;T<=C;T++)
{
if(flag) System.out.println();
else flag=true;
maxsum=Integer.MIN_VALUE;
n=cin.nextInt();
System.out.println("Case "+T+":");
for(i=0;i<n;i++)
{
A[i]=cin.nextInt();
}
nowsum=A[0];
maxsum=A[0];
int start = 0,end = 0,endstart=0;
for(i=1;i<n;i++)
{
if(nowsum>=0) nowsum+=A[i];
else {nowsum=A[i];start=i;}
if(nowsum>maxsum){
endstart=start;
maxsum=nowsum;
end=i;
}
}
endstart++;end++;
System.out.println(maxsum+" "+endstart+" "+end);
}


============================我是被人抛弃的昏割线============================

Max Sum Plus Plus

Problem Description
Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we always challenge ourselves to more difficult problems. Now you are faced with a more difficult problem.

Given a consecutive number sequence S1, S2, S3, S4 ... Sx, ... Sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767). We define a function sum(i, j) = Si + ... + Sj (1 ≤ i ≤ j ≤ n).

Now given an integer m (m > 0), your task is to find m pairs of i and j which make sum(i1, j1) + sum(i2, j2) + sum(i3, j3) + ... + sum(im, jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx is not allowed).

But I`m lazy, I don't want to write a special-judge module, so you don't have to output m pairs of i and j, just output the maximal summation of sum(ix, jx)(1 ≤ x ≤ m) instead. ^_^

Input

Each test case will begin with two integers m and n, followed by n integers S1, S2, S3 ... Sn.
Process to the end of file.

Output

Output the maximal summation described above in one line.

Sample Input

1 3 1 2 3
2 6 -1 4 -2 3 -2 3


Sample Output

6
8


Hint

Huge input, scanf and dynamic programming is recommended.
--------------------
这题表示不会ing 先放这里
============================我是被人抛弃的昏割线============================

Constructing Roads In JGShining's Kingdom

Problem Description
JGShining's kingdom consists of 2n(n is no more than 500,000) small cities which are located in two parallel lines.

Half of these cities are rich in resource (we call them rich cities) while the others are short of resource (we call them poor cities). Each poor city is short of exactly one kind of resource and also each rich city is rich in exactly one kind of resource. You may assume no two poor cities are short of one same kind of resource and no two rich cities are rich in one same kind of resource.

With the development of industry, poor cities wanna import resource from rich ones. The roads existed are so small that they're unable to ensure the heavy trucks, so new roads should be built. The poor cities strongly BS each other, so are the rich ones. Poor cities don't wanna build a road with other poor ones, and rich ones also can't abide sharing an end of road with other rich ones. Because of economic benefit, any rich city will be willing to export resource to any poor one.

Rich citis marked from 1 to n are located in Line I and poor ones marked from 1 to n are located in Line II.

The location of Rich City 1 is on the left of all other cities, Rich City 2 is on the left of all other cities excluding Rich City 1, Rich City 3 is on the right of Rich City 1 and Rich City 2 but on the left of all other cities ... And so as the poor ones.

But as you know, two crossed roads may cause a lot of traffic accident so JGShining has established a law to forbid constructing crossed roads.

For example, the roads in Figure I are forbidden.



In order to build as many roads as possible, the young and handsome king of the kingdom - JGShining needs your help, please help him. ^_^

Input

Each test case will begin with a line containing an integer n(1 ≤ n ≤ 500,000). Then n lines follow. Each line contains two integers p and r which represents that Poor City p needs to import resources from Rich City r. Process to the end of file.

Output

For each test case, output the result in the form of sample.
You should tell JGShining what's the maximal number of road(s) can be built.

Sample Input

2
1 2
2 1
3
1 2
2 3
3 1


Sample Output

Case 1:
My king, at most 1 road can be built.

Case 2:
My king, at most 2 roads can be built.


Hint

Huge input, scanf is recommended.

--------------------
这题也不会T T,用到传说中的单调队列 T T,不用都没想出来 T T,以后DP神马的别找我了T T

============================我是被人抛弃的昏割线============================

Humble Numbers

Problem Description
A number whose only prime factors are 2,3,5 or 7 is called a humble number. The sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, ... shows the first 20 humble numbers.

Write a program to find and print the nth element in this sequence

Input

The input consists of one or more test cases. Each test case consists of one integer n with 1 <= n <= 5842. Input is terminated by a value of zero (0) for n.

Output

For each test case, print one line saying "The nth humble number is number.". Depending on the value of n, the correct suffix "st", "nd", "rd", or "th" for the ordinal number nth has to be used like it is shown in the sample output.

Sample Input

1
2
3
4
11
12
13
21
22
23
100
1000
5842
0


Sample Output

The 1st humble number is 1.
The 2nd humble number is 2.
The 3rd humble number is 3.
The 4th humble number is 4.
The 11th humble number is 12.
The 12th humble number is 14.
The 13th humble number is 15.
The 21st humble number is 28.
The 22nd humble number is 30.
The 23rd humble number is 32.
The 100th humble number is 450.
The 1000th humble number is 385875.
The 5842nd humble number is 2000000000.


--------------------
POJ上有个类似的题,不会,问喵呜大神,第一次知道动态规划这个词。当时那个题我几乎是打表做的了,这题预处理,按顺序把这个序列先算出来,主要是个顺序问题,而且不能重复。这题不是自己想出来的,因为原先看了别人写的,硬记住了。。
#include <iostream>
using namespace std;
int min(int x,int y)
{
return x<y?x:y;
}
int main()
{
int n,x2=1,x3=1,x5=1,x7=1,i;
long long A[5843]={0,1};
for(i=2;i<=5842;i++)
{
A[i]=min(A[x2]*2,min(A[x3]*3,min(A[x5]*5,A[x7]*7)));
if(A[i]==A[x2]*2) {x2++;}
if(A[i]==A[x3]*3) {x3++;}
if(A[i]==A[x5]*5) {x5++;}
if(A[i]==A[x7]*7) {x7++;}
}
while(cin>>n)
{
if(n==0) return 0;
if(n%10==1&&n%100!=11) {cout << "The "<<n<<"st humble number is "<<A
<<"."<<endl;continue;}
if(n%10==2&&n%100!=12) {cout << "The "<<n<<"nd humble number is "<<A
<<"."<<endl;continue;}
if(n%10==3&&n%100!=13) {cout << "The "<<n<<"rd humble number is "<<A
<<"."<<endl;continue;}
cout << "The "<<n<<"th humble number is "<<A
<<"."<<endl;
}
return 0;
}

============================我是被人抛弃的昏割线============================

Dividing

Problem Description
Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of the marbles. This would be easy if all the marbles had the same value, because then they could just split the collection in half. But unfortunately, some of the marbles are larger, or more beautiful than others. So, Marsha and Bill start by assigning a value, a natural number between one and six, to each marble. Now they want to divide the marbles so that each of them gets the same total value.
Unfortunately, they realize that it might be impossible to divide the marbles in this way (even if the total value of all marbles is even). For example, if there are one marble of value 1, one of value 3 and two of value 4, then they cannot be split into sets of equal value. So, they ask you to write a program that checks whether there is a fair partition of the marbles.

Input

Each line in the input describes one collection of marbles to be divided. The lines consist of six non-negative integers n1, n2, ..., n6, where ni is the number of marbles of value i. So, the example from above would be described by the input-line ``1 0 1 2 0 0''. The maximum total number of marbles will be 20000.

The last line of the input file will be ``0 0 0 0 0 0''; do not process this line.

Output

For each colletcion, output ``Collection #k:'', where k is the number of the test case, and then either ``Can be divided.'' or ``Can't be divided.''.

Output a blank line after each test case.

Sample Input

1 0 1 2 0 0
1 0 0 0 1 1
0 0 0 0 0 0


Sample Output

Collection #1:
Can't be divided.

Collection #2:
Can be divided.

--------------------

多重背包,像喵呜大神转的那个日志一样,数据结构课本上的算法会TLE - -

#include<cstdio>
using namespace std;
struct bg {
int c,w,n;
} bag[10];
int dp[120005];
int V;

int max(int x,int y)
{
return x>y?x:y;
}

void CPack(int cost,int weight)
{
for(int i=cost;i<=V;i++)
{
dp[i]=max(dp[i],dp[i-cost]+weight);
}
}

void ZPack(int cost,int weight)
{
for(int i=V;i>=cost;i--)
{
dp[i]=max(dp[i],dp[i-cost]+weight);
}
}

void MPack(int cost,int weight,int amount)
{
if(cost*amount>=V)
{
CPack(cost,weight);
return;
}
int k=1;
while( k<amount )
{
ZPack(k*cost,k*weight);
amount=amount-k;
k*=2;
}
ZPack(amount*cost,amount*weight);
}

int main()
{
int i;
for(i=0;i<6;i++)
{
bag[i].w=1;
bag[i].c=i+1;
}
int sumweight;
int T=1;
while( scanf("%d",&bag[0].n)==1 )
{
sumweight=bag[0].n*1;
for(i=1;i<6;i++)
{
scanf("%d",&bag[i].n );
sumweight+=bag[i].n*(i+1);
}
if(bag[1].n==0&&bag[2].n==0&&bag[3].n==0&&bag[4].n==0&&bag[5].n==0&&bag[0].n==0) return 0;
for(i=1;i<=120003;i++)
{
dp[i]=-99999999;
}
dp[0]=0;
printf("Collection #%d:/n",T++);
if(sumweight%2==1) {printf("Can't be divided./n/n");continue;}
V=sumweight/2;
for(i=0;i<6;i++)
{
MPack( bag[i].c,bag[i].w,bag[i].n );
}
if( dp[V]>0 )
{
printf("Can be divided./n/n");
}
else
{
printf("Can't be divided./n/n");
}

}

return 0;
}
[/code]
============================我是被人抛弃的昏割线============================

Monkey and Banana

Problem Description A group of researchers are designing an experiment to test the IQ of a monkey. They will hang a banana at the roof of a building, and at the mean time, provide the monkey with some blocks. If the monkey is clever enough, it shall be able to reach the banana by placing one block on the top another to build a tower and climb up to get its favorite food. The researchers have n types of blocks, and an unlimited supply of blocks of each type. Each type-i block was a rectangular solid with linear dimensions (xi, yi, zi). A block could be reoriented so that any two of its three dimensions determined the dimensions of the base and the other dimension was the height. They want to make sure that the tallest tower possible by stacking blocks can reach the roof. The problem is that, in building a tower, one block could only be placed on top of another block as long as the two base dimensions of the upper block were both strictly smaller than the corresponding base dimensions of the lower block because there has to be some space for the monkey to step on. This meant, for example, that blocks oriented to have equal-sized bases couldn't be stacked. Your job is to write a program that determines the height of the tallest tower the monkey can build with a given set of blocks.

Input

The input file will contain one or more test cases. The first line of each test case contains an integer n, representing the number of different blocks in the following data set. The maximum value for n is 30. Each of the next n lines contains three integers representing the values xi, yi and zi. Input is terminated by a value of zero (0) for n.

Output

For each test case, print one line containing the case number (they are numbered sequentially starting from 1) and the height of the tallest possible tower in the format "Case case: maximum height = height".

Sample Input

[code]1 10 20 30 2 6 8 10 5 5 5 7 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 5 31 41 59 26 53 58 97 93 23 84 62 64 33 83 27

0


Sample Output

Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342

--------------------

这个是矩形嵌套问题么?我的大概思路:每个blocks为3个矩形(长宽高组合),建立一个有向无环图,然后DP。

这样做AC了,不知道正统做法是神马,先附个自己写的代码吧

#include<cstdio>
#include<cstring>
using namespace std;
int max(int x,int y)
{
return x>y?x:y;
}

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

bool G[105][105];
int dpx[105];
int n;
struct nod {
int x,y;
int h;
} A[105];

int dp(int x)
{
if(dpx[x]!=-1) return dpx[x];
int i,tmp=0;
int max=0;
for(i=0;i<n*3;i++)
{
if(G[x][i])
{
tmp=dp(i);
if( max<tmp ) max=tmp;
}
}
dpx[x]=max+ A[x].h;
return dpx[x];
}

int main()
{
int T=1;
int i,j;
int a,b,c,d,e,f;
int maxn,tmp;
while( scanf("%d",&n)==1 )
{
if(n==0) return 0;
maxn=-99;
memset(dpx,-1,sizeof(dpx));
memset(G,0,sizeof(G));
for(i=0;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
f=max(a,max(b,c));
d=min(a,min(b,c));
e=a+b+c-f-d;
A[i*3].x=d;A[i*3].y=e;A[i*3].h=f;
A[i*3+1].x=d;A[i*3+1].y=f;A[i*3+1].h=e;
A[i*3+2].x=e;A[i*3+2].y=f;A[i*3+2].h=d;
}
for(i=0;i<n*3;i++)
{
for(j=0;j<n*3;j++)
{
if(A[i].x<A[j].x&&A[i].y<A[j].y) G[i][j]=true;
}
}

for(i=0;i<n*3;i++)
{
tmp=dp(i);
if(maxn<tmp) maxn=tmp;
}
printf("Case %d: maximum height = %d/n",T++,maxn);

}
return 0;
}
[/code]
============================我是被人抛弃的昏割线============================

Human Gene Functions


[/code]
Problem Description	It is well known that a human gene can be considered as a sequence, consisting of four nucleotides, which are simply denoted by four letters, A, C, G, and T. Biologists have been interested in identifying human genes and determining their functions, because these can be used to diagnose human diseases and to design new drugs for them.

A human gene can be identified through a series of time-consuming biological experiments, often with the help of computer programs. Once a sequence of a gene is obtained, the next job is to determine its function. One of the methods for biologists to use in determining the function of a new gene sequence that they have just identified is to search a database with the new gene as a query. The database to be searched stores many gene sequences and their functions – many researchers have been submitting their genes and functions to the database and the database is freely accessible through the Internet.

A database search will return a list of gene sequences from the database that are similar to the query gene. Biologists assume that sequence similarity often implies functional similarity. So, the function of the new gene might be one of the functions that the genes from the list have. To exactly determine which one is the right one another series of biological experiments will be needed.

Your job is to make a program that compares two genes and determines their similarity as explained below. Your program may be used as a part of the database search if you can provide an efficient one.

Given two genes AGTGATG and GTTAG, how similar are they? One of the methods to measure the similarity of two genes is called alignment. In an alignment, spaces are inserted, if necessary, in appropriate positions of the genes to make them equally long and score the resulting genes according to a scoring matrix.

For example, one space is inserted into AGTGATG to result in AGTGAT-G, and three spaces are inserted into GTTAG to result in –GT--TAG. A space is denoted by a minus sign (-). The two genes are now of equal length. These two strings are aligned:

AGTGAT-G
-GT--TAG

In this alignment, there are four matches, namely, G in the second position, T in the third, T in the sixth, and G in the eighth. Each pair of aligned characters is assigned a score according to the following scoring matrix.



* denotes that a space-space match is not allowed. The score of the alignment above is (-3)+5+5+(-2)+(-3)+5+(-3)+5=9.

Of course, many other alignments are possible. One is shown below (a different number of spaces are inserted into different positions):

AGTGATG
-GTTA-G

This alignment gives a score of (-3)+5+5+(-2)+5+(-1) +5=14. So, this one is better than the previous one. As a matter of fact, this one is optimal since no other alignment can have a higher score. So, it is said that the similarity of the two genes is 14.

Input

The input consists of T test cases. The number of test cases ) (T is given in the first line of the input. Each test case consists of two lines: each line contains an integer, the length of a gene, followed by a gene sequence. The length of each gene sequence is at least one and does not exceed 100.

Output

The output should print the similarity of each test case, one per line.

Sample Input

[code]2 7 AGTGATG 5 GTTAG 7 AGCTATT 9 AGCTTTAAA


Sample Output

14
21

--------------------

好像还是最长公共子序列,不过有些变动,就不会了。。orz 以后再说吧

此题有一个想法,不过实现有些麻烦,也不知道对不对,所以先放着了。。

============================我是被人抛弃的昏割线============================

To The Max

Problem Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1 x 1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. In this problem the sub-rectangle with the largest sum is referred to as the maximal sub-rectangle. As an example, the maximal sub-rectangle of the array: 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 is in the lower left corner: 9 2 -4 1 -1 8 and has a sum of 15.

Input

The input consists of an N x N array of integers. The input begins with a single positive integer N on a line by itself, indicating the size of the square two-dimensional array. This is followed by N 2 integers separated by whitespace (spaces and newlines). These are the N 2 integers of the array, presented in row-major order. That is, all numbers in the first row, left to right, then all numbers in the second row, left to right, etc. N may be as large as 100. The numbers in the array will be in the range [-127,127].

Output

Output the sum of the maximal sub-rectangle.

Sample Input

4 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2


Sample Output

15

-----------------------------

想了很久的一道题,没想出来。。喵呜大神说直接行枚举即可,AC了。。膜拜。。

做法同1003,不同之处就是把行加起来,然后再DP

#include<cstdio>
#include<cstring>
using namespace std;
int n;
int A[101][101];
int tmp[101][101];

int max(int a,int b)
{
return a>b?a:b;
}

void tran(int x,int lin1)
{
int i,j,k;
for(i=0;i<lin1;i++)
{
for(j=0;j<n;j++)
{
tmp[i][j]=0;
for(k=i;k<i+x;k++)
{
tmp[i][j]+=A[k][j];
}
}
}
}

int prom(int x)
{
int lmax=-9999999;
int nowsum,maxsum,i,l;
int lin1=n-x+1;
tran(x,lin1);
for(l=0;l<lin1;l++)
{
nowsum=tmp[l][0];
maxsum=tmp[l][0];
for(i=1;i<n;i++)
{
if(nowsum>=0) nowsum+=tmp[l][i];
else nowsum=tmp[l][i];
if(nowsum>maxsum){
maxsum=nowsum;
}
}
lmax=max(lmax,maxsum);
}
return lmax;
}

int main()
{
int i,j,tmax,ttmp;
while( scanf("%d",&n)==1 )
{
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&A[i][j]);
}
}
tmax=-99999999;
for(i=1;i<=n;i++)
{
ttmp=prom(i);
tmax=max(tmax,ttmp);
}
printf("%d/n",tmax);

}
return 0;
}
[/code]
============================我是被人抛弃的昏割线============================

Piggy-Bank

Problem 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 Input310 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<cstdio>
using namespace std;
struct bg {
int c,w;
} bag[505];
int dp[10005];
int V;

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

void CPack(int cost,int weight)
{
for(int i=cost;i<=V;i++)
{
dp[i]=min(dp[i],dp[i-cost]+weight);
}
}

int main()
{
int T,i,E,F,n;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&E,&F);
V=F-E;
scanf("%d",&n);
for(i=1;i<=10003;i++)
{
dp[i]=99999999;
}
dp[0]=0;
for(i=1;i<=n;i++)
{
scanf("%d%d",&bag[i].w,&bag[i].c);
}
for(i=1;i<=n;i++)
{
CPack( bag[i].c,bag[i].w );
}
if(dp[V]!=99999999) printf("The minimum amount of money in the piggy-bank is %d./n",dp[V]);
else printf("This is impossible./n");
}
return 0;
}
[/code]
============================我是被人抛弃的昏割线============================

Common Subsequence

Problem 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, xij = 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. The program input is from a text file. Each data set in the file contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct. 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<cstdio>
#include<cstring>
using namespace std;
short max( short x,short y)
{
return x>y?x:y;
}
int main()
{
char A[500],B[500];
int lenA,lenB,i,j;
while(scanf("%s%s",A,B)==2)
{
short dp[502][502]={0};
lenA=strlen(A);
lenB=strlen(B);
for(i=1;i<=lenA;i++)
{
for(j=1;j<=lenB;j++)
{
if( A[i-1]==B[j-1] ) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=max( dp[i-1][j],dp[i][j-1] );
}
}
printf("%d/n",dp[lenA][lenB]);
}
return 0;
}
[/code]
============================我是被人抛弃的昏割线============================

免费馅饼

Problem Description都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内。馅饼如果掉在了地上当然就不能吃了,所以gameboy马上卸下身上的背包去接。但由于小径两侧都不能站人,所以他只能在小径上接。由于gameboy平时老呆在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒种只有在移动不超过一米的范围内接住坠落的馅饼。现在给这条小径如图标上坐标: 为了使问题简化,假设在接下来的一段时间里,馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼?(假设他的背包可以容纳无穷多个馅饼)

Input

输入数据有多组。每组数据的第一行为以正整数n(0<n<100000),表示有n个馅饼掉在这条小径上。在结下来的n行中,每行有两个整数x,T(0<T<100000),表示在第T秒有一个馅饼掉在x点上。同一秒钟在同一点上可能掉下多个馅饼。n=0时输入结束。

Output

每一组输入数据对应一行输出。输出一个整数m,表示gameboy最多可能接到m个馅饼。 提示:本题的输入数据量比较大,建议用scanf读入,用cin可能会超时。

Sample Input

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

Sample Output


4

--------------------------------

SSY同学已经写了这个题,有点像数塔,一层一层的,我也挂个代码吧。

#include<cstdio>
#include<cstring>
using namespace std;
int A[100002][11];
//int A[10][11];
int max(int x,int y)
{
return x>y?x:y;
}

int main()
{
int n,p,q,i,dep;
while(scanf("%d",&n)==1)
{
dep=0;
memset(A,0,sizeof(A));
if(n==0) return 0;
for(i=0;i<n;i++)
{
scanf("%d%d",&p,&q);
A[q][p]++;
if(dep<q) dep=q;
}
int j,k;
for(i=dep-1;i>0;i--)
{
A[i][0]+=max(A[i+1][0],A[i+1][1]);
A[i][10]+=max(A[i+1][10],A[i+1][9]);
for(j=1;j<10;j++)
{
A[i][j]+=max(A[i+1][j-1],max(A[i+1][j],A[i+1][j+1]));
}
}
printf("%d/n",max(A[1][5],max(A[1][4],A[1][6])));
}
return 0;
}
[/code]
============================我是被人抛弃的昏割线============================

最少拦截系统

Problem Description某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统.

Input

输入若干组数据.每组数据包括:导弹总个数(正整数),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)

Output

对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统.

Sample Input

8 389 207 155 300 299 170 158 65


Sample Output

2

--------------------------

这道题AC了,但最近觉得我的算法是错的。。orz 先挂上,等我想想吧。。我觉得我是按贪心做的,可这是很经典的一个DP啊。。

输入要求给的数据太少了,数组建多少都不知道,就用了vector。。。其实没必要的。。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{
int n;
while(cin >> n)
{
int i,j,now;
vector<int> A;
A.push_back(30005);
bool flag;
for(i=0;i<n;i++)
{
flag=true;
cin >> now;
for(j=0;j<A.size();j++)
{
if( A[j]>=now ) {A[j]=now;flag=false;break;}
}
if(flag) A.push_back(now);
sort(A.begin(),A.end());
}
cout << A.size() << endl;
}
return 0;
}
[/code]

[/code]
[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: