dt-动态规划dp加贪心

A - Radar Installation

POJ - 1328

Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d.

We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates.


Figure A Sample Input of Radar Installations



Input

The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases.

The input is terminated by a line containing pair of zeros

Output

For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case.

Sample Input

3 2
1 2
-3 1
2 1

1 2
0 2

0 0

Sample Output

Case 1: 2
Case 2: 1
#include"stdio.h"
#include"cstdio"
#include"algorithm"
#include"math.h"
using namespace std;
const int max_n=1e3+10;
pair <double,double> point[max_n];
int main()
{
    int n,d,j=0;
    double x,y;
    while(scanf("%d%d",&n,&d)!=EOF)
    {
        if(n==0&&d==0) break;
        int i,m=1,count=1;
        if(d<=0) m=-1;
        for(i=1;i<=n;i++) 
        {
            scanf("%lf%lf",&x,&y);
            point[i].first=x-sqrt(double(d*d-y*y));
            point[i].second=x+sqrt(double(d*d-y*y));
            if(y>d) m=-1;
        }
        sort(point+1,point+1+n);
        double a=point[1].second;
        for(i=2;i<=n;i++)
        {
            if(point[i].first>a)
            {
                count++;a=point[i].second;
            }
            else if(point[i].secondpoint[i].second;
        }
        if(m<0) count=-1;
        printf("Case %d: %d\n",++j,count);
    }
} 

B - Case of Fugitive

CodeForces - 556D                    

Andrewid the Android is a galaxy-famous detective. He is now chasing a criminal hiding on the planet Oxa-5, the planet almost fully covered with water.

The only dry land there is an archipelago of n narrow islands located in a row. For more comfort let's represent them as non-intersecting segments on a straight line: island i has coordinates [li, ri], besides, ri < li + 1 for 1 ≤ i ≤ n - 1.

To reach the goal, Andrewid needs to place a bridge between each pair of adjacent islands. A bridge of length a can be placed between the i-th and the (i + 1)-th islads, if there are such coordinates of x and y, that li ≤ x ≤ ri, li + 1 ≤ y ≤ ri + 1 and y - x = a.

The detective was supplied with m bridges, each bridge can be used at most once. Help him determine whether the bridges he got are enough to connect each pair of adjacent islands.

Input

The first line contains integers n (2 ≤ n ≤ 2·105) and m (1 ≤ m ≤ 2·105) — the number of islands and bridges.

Next n lines each contain two integers li and ri (1 ≤ li ≤ ri ≤ 1018) — the coordinates of the island endpoints.

The last line contains m integer numbers a1, a2, ..., am (1 ≤ ai ≤ 1018) — the lengths of the bridges that Andrewid got.

Output

If it is impossible to place a bridge between each pair of adjacent islands in the required manner, print on a single line "No" (without the quotes), otherwise print in the first line "Yes" (without the quotes), and in the second line print n - 1 numbers b1, b2, ..., bn - 1, which mean that between islands i and i + 1 there must be used a bridge number bi.

If there are multiple correct answers, print any of them. Note that in this problem it is necessary to print "Yes" and "No" in correct case.

Example

Input
4 4
1 4
7 8
9 10
12 14
4 5 3 8
Output
Yes
2 3 1
Input
2 2
11 14
17 18
2 9
Output
No
Input
2 1
1 1
1000000000000000000 1000000000000000000
999999999999999999
Output
Yes
1

Note

In the first sample test you can, for example, place the second bridge between points 3 and 8, place the third bridge between points 7 and 10 and place the first bridge between points 10 and 14.

In the second sample test the first bridge is too short and the second bridge is too long, so the solution doesn't exist.

C - Coin Change

HDU - 2069                    

Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 1-cent. We want to make changes with these coins for a given amount of money.

For example, if we have 11 cents, then we can make changes with one 10-cent coin and one 1-cent coin, or two 5-cent coins and one 1-cent coin, or one 5-cent coin and six 1-cent coins, or eleven 1-cent coins. So there are four ways of making changes for 11 cents with the above coins. Note that we count that there is one way of making change for zero cent.

Write a program to find the total number of different ways of making changes for any amount of money in cents. Your program should be able to handle up to 100 coins.
InputThe input file contains any number of lines, each one consisting of a number ( ≤250 ) for the amount of money in cents.OutputFor each input line, output a line containing the number of different ways of making changes with the above 5 types of coins.Sample Input

11
26

Sample Output

4
13
#include"stdio.h"
#include"cstdio" 
using namespace std;
const int max_n=2*(1e2)+60;
int A[6]={0,1,5,10,25,50};
int dp1[max_n][110],dp2[max_n][110];
int res[max_n];
int main()
{
    int i,j,k,p;
    dp1[0][0]=1;
    for(i=1;i<=5;i++)
    {
        for(j=0;j<=250;j++)
        {
            for(k=0;j+k*A[i]<=250;k++)
            {
                for(p=0;k+p<=100;p++)
                dp2[j+k*A[i]][p+k]+=dp1[j][p];    
            }    
        }    
        for(j=1;j<=250;j++)
        {
            for(p=0;p<=100;p++)
            {
                dp1[j][p]=dp2[j][p];dp2[j][p]=0;
            }
        }
    } 
    for(i=0;i<=250;i++)
    {
        for(j=0;j<=100;j++)
        res[i]+=dp1[i][j]; 
    }
    int n;
    while(scanf("%d",&n)!=EOF)
    printf("%d\n",res[n]);
}

D - 数塔

HDU - 2084                    

在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的:

有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?

已经告诉你了,这是个DP的题目,你能AC吗?Input输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间0,990,99 内。
Output对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。
Sample Input

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

Sample Output

30
#include"stdio.h"
#include"cstdio"
#include"algorithm"
using namespace std;
const int max_n=110;
int A[max_n][max_n],dp[max_n][max_n];
int main()
{
    int k,n,i,j;
    scanf("%d",&k);
    while(k--)
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=i;j++)
            {
                scanf("%d",&A[i][j]);
            }
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=i;j++)
            {
                dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+A[i][j];
            }
        }
        sort(dp[n]+1,dp[n]+n+1);
        printf("%d\n",dp[n][n]);
    }
}

E - 选课时间(题目已修改,注意读题)

HDU - 2079

又到了选课的时间了,xhd看着选课表发呆,为了想让下一学期好过点,他想知道学n个学分共有多少组合。你来帮帮他吧。(xhd认为一样学分的课没区别)
Input输入数据的第一行是一个数据T,表示有T组数据。
每组数据的第一行是两个整数n(1 <= n <= 40),k(1 <= k <= 8)。
接着有k行,每行有两个整数a(1 <= a <= 8),b(1 <= b <= 10),表示学分为a的课有b门。
Output对于每组输入数据,输出一个整数,表示学n个学分的组合数。
Sample Input

2
2 2
1 2
2 1
40 8
1 1
2 2
3 2
4 2
5 8
6 9
7 6
8 8

Sample Output

2
445
#include"stdio.h"
#include"cstdio"
#include"algorithm"
using namespace std;
const int max_n=50;
int dp[9][max_n];
int A[9];
int main()
{
    int n,k,t;
    while(scanf("%d",&t)!=EOF)
    {
        while(t--)
        {
            int i,j,a,b,q;
            scanf("%d%d",&n,&k);
            //fill(A,A+n,0);
            for(i=0;i<=8;i++)
            {
                A[i]=0; 
                for(j=0;j<=n;j++)
                dp[i][j]=0;
            }
            for(i=1;i<=k;i++)
            {
                scanf("%d%d",&a,&b);
                A[a]=b;
            }
            dp[0][0]=1;
            for(i=0;i<=7;i++)
            {
                for(j=0;j<=n;j++)
                {
                    for(q=0;q*(i+1)<=j&&q<=A[i+1];q++)
                    dp[i+1][j]+=dp[i][j-q*(i+1)];
                }
            }
            printf("%d\n",dp[8][n]);
        }
    }
} 

F - Crossing River

POJ - 1700                    

A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat back and forth so that all people may cross. Each person has a different rowing speed; the speed of a couple is determined by the speed of the slower one. Your job is to determine a strategy that minimizes the time for these people to get across.Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. The first line of each case contains N, and the second line contains N integers giving the time for each people to cross the river. Each case is preceded by a blank line. There won't be more than 1000 people and nobody takes more than 100 seconds to cross.

Output

For each test case, print a line containing the total number of seconds required for all the N people to cross the river.

Sample Input

1
4
1 2 5 10

Sample Output

17
#include"stdio.h"
#include"cstdio"
#include"algorithm"
#include"string.h"
using namespace std;
const int max_n=1e3+10;
int A[max_n];
int dp[max_n]; 
int main()
{
    int i,j,n,t;
    while(scanf("%d",&t)!=EOF)
    {
        memset(A,0,sizeof(A));
        while(t--)
        {
            scanf("%d",&n);
            for(i=0;i)
            {
                scanf("%d",&A[i]);
            }
            sort(A,A+n);
            dp[1]=A[0];dp[0]=0;dp[2]=A[1]; 
            for(i=2;i<=n-1;i++)
            {
                dp[i+1]=min(dp[i]+A[i]+A[0],dp[i-1]+A[0]+A[i]+2*A[1]);
            }
            printf("%d\n",dp[n]);
        }
    }
}

G - 今年暑假不AC

HDU - 2037                    

“今年暑假不AC?”
“是的。”
“那你干什么呢?”
“看世界杯呀,笨蛋!”
“@#$%^&*%...”

确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了。
作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)
Input输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。
Output对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。Sample Input

12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0

Sample Output

5
#include"stdio.h"
#include"cstdio"
#include"algorithm"
using namespace std;
const int max_n=110;
int time[2][max_n];
pair<int,int> itv[max_n];
int main()
{
    int n,i,j;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        for(i=1;i<=n;i++) 
        {
            scanf("%d%d",&time[0][i],&time[1][i]);
            itv[i].first=time[1][i];itv[i].second=time[0][i];
        }
        sort(itv+1,itv+1+n);
        int t=0,m=0;
        for(i=1;i<=n;i++)
        {
            if(t<=itv[i].second)
            {
                t=itv[i].first;
                m++;
            }
        }
        printf("%d\n",m);
    }
}

H - Common Subsequence

HDU - 1159                    

A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = another sequence Z = is a subsequence of X if there exists a strictly increasing sequence of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = is a subsequence of X = 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.
Input

abcfbc abfcab
programming contest 
abcd mnp

Output

4
2
0

Sample Input

abcfbc abfcab
programming contest 
abcd mnp

Sample Output

4
2
0

I - 免费馅饼

HDU - 1176                     
都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内。馅饼如果掉在了地上当然就不能吃了,所以gameboy马上卸下身上的背包去接。但由于小径两侧都不能站人,所以他只能在小径上接。由于gameboy平时老呆在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒种只有在移动不超过一米的范围内接住坠落的馅饼。现在给这条小径如图标上坐标:

为了使问题简化,假设在接下来的一段时间里,馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼?(假设他的背包可以容纳无穷多个馅饼)
Input输入数据有多组。每组数据的第一行为以正整数n(0Output每一组输入数据对应一行输出。输出一个整数m,表示gameboy最多可能接到m个馅饼。
提示:本题的输入数据量比较大,建议用scanf读入,用cin可能会超时。

Sample Input
6
5 1
4 1
6 1
7 2
7 2
8 3
0
Sample Output
4

J - 计算字符串距离

OpenJ_Bailian - 4007    
对于两个不同的字符串,我们有一套操作方法来把他们变得相同,具体方法为:
  1. 修改一个字符(如把“a”替换为“b”)
  2. 删除一个字符(如把“traveling”变为“travelng”)

比如对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加/减少一个“g”的方式来达到目的。无论增加还是减少“g”,我们都仅仅需要一次操作。我们把这个操作所需要的次数定义为两个字符串的距离。
给定任意两个字符串,写出一个算法来计算出他们的距离。Input 第一行有一个整数n。表示测试数据的组数,
接下来共n行,每行两个字符串,用空格隔开。表示要计算距离的两个字符串
字符串长度不超过1000。 Output 针对每一组测试数据输出一个整数,值为两个字符串的距离。 Sample Input
3
abcdefg  abcdef
ab ab
mnklj jlknm
Sample Output
1
0
4

K - 开餐馆

OpenJ_Bailian - 4118 

   

北大信息学院的同学小明毕业之后打算创业开餐馆.现在共有n 个地点可供选择。小明打算从中选择合适的位置开设一些餐馆。这 n 个地点排列在同一条直线上。我们用一个整数序列m1, m2, ... mn 来表示他们的相对位置。由于地段关系,开餐馆的利润会有所不同。我们用pi 表示在mi 处开餐馆的利润。为了避免自己的餐馆的内部竞争,餐馆之间的距离必须大于k。请你帮助小明选择一个总利润最大的方案。

 

Input 标准的输入包含若干组测试数据。输入第一行是整数T (1 <= T <= 1000) ,表明有T组测试数据。紧接着有T组连续的测试。每组测试数据有3行, 
第1行:地点总数 n (n < 100), 距离限制 k (k > 0 && k < 1000).
第2行:n 个地点的位置m1 , m2, ... mn ( 1000000 > mi > 0 且为整数,升序排列)
第3行:n 个地点的餐馆利润p1 , p2, ... pn ( 1000 > pi > 0 且为整数) Output 对于每组测试数据可能的最大利润 Sample Input
2
3 11
1 2 15
10 2 30
3 16
1 2 15
10 2 30
Sample Output
40
30

L - Bone Collector

HDU - 2602                     
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave … 
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?

InputThe first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.OutputOne integer per line representing the maximum of the total value (this number will be less than 2 31).Sample Input
1
5 10
1 2 3 4 5
5 4 3 2 1
Sample Output
14

M - I NEED A OFFER!

HDU - 1203 
Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了。要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的。Speakless没有多少钱,总共只攒了n万美元。他将在m个学校中选择若干的(当然要在他的经济承受范围内)。每个学校都有不同的申请费用a(万美元),并且Speakless估计了他得到这个学校offer的可能性b。不同学校之间是否得到offer不会互相影响。“I NEED A OFFER”,他大叫一声。帮帮这个可怜的人吧,帮助他计算一下,他可以收到至少一份offer的最大概率。(如果Speakless选择了多个学校,得到任意一个学校的offer都可以)。
Input输入有若干组数据,每组数据的第一行有两个正整数n,m(0<=n<=10000,0<=m<=10000)
后面的m行,每行都有两个数据ai(整型),bi(实型)分别表示第i个学校的申请费用和可能拿到offer的概率。
输入的最后有两个0。
Output每组数据都对应一个输出,表示Speakless可能得到至少一份offer的最大概率。用百分数表示,精确到小数点后一位。
Sample Input
10 3
4 0.1
4 0.2
5 0.3
0 0
Sample Output
44.0%


        
 
Hint
You should use printf("%%") to print a '%'.

N - The trouble of Xiaoqian

HDU - 3591 
In the country of ALPC , Xiaoqian is a very famous mathematician. She is immersed in calculate, and she want to use the minimum number of coins in every shopping. (The numbers of the shopping include the coins she gave the store and the store backed to her.)
And now , Xiaoqian wants to buy T (1 ≤ T ≤ 10,000) cents of supplies. The currency system has N (1 ≤ N ≤ 100) different coins, with values V1, V2, ..., VN (1 ≤ Vi ≤ 120). Xiaoqian is carrying C1 coins of value V1, C2 coins of value V2, ...., and CN coins of value VN (0 ≤ Ci ≤ 10,000). The shopkeeper has an unlimited supply of all the coins, and always makes change in the most efficient manner .But Xiaoqian is a low-pitched girl , she wouldn’t like giving out more than 20000 once.
InputThere are several test cases in the input.
Line 1: Two space-separated integers: N and T.
Line 2: N space-separated integers, respectively V1, V2, ..., VN coins (V1, ...VN)
Line 3: N space-separated integers, respectively C1, C2, ..., CN
The end of the input is a double 0.
OutputOutput one line for each test case like this ”Case X: Y” : X presents the Xth test case and Y presents the minimum number of coins . If it is impossible to pay and receive exact change, output -1.Sample Input
3 70
5 25 50
5 2 1
0 0
Sample Output
Case 1: 3

             

转载于:https://www.cnblogs.com/lch316/p/6771085.html

你可能感兴趣的:(dt-动态规划dp加贪心)