poj3666+poj1745+poj3616(dp)

http://poj.org/problem?id=3666

A straight dirt road connects two fields on FJ's farm, but it changes elevation more than FJ would like. His cows do not mind climbing up or down a single slope, but they are not fond of an alternating succession of hills and valleys. FJ would like to add and remove dirt from the road so that it becomes one monotonic slope (either sloping up or down).

You are given N integers A1, ... , AN (1 ≤ N ≤ 2,000) describing the elevation (0 ≤ Ai ≤ 1,000,000,000) at each of N equally-spaced positions along the road, starting at the first field and ending at the other. FJ would like to adjust these elevations to a new sequence B1, . ... , BN that is either nonincreasing or nondecreasing. Since it costs the same amount of money to add or remove dirt at any position along the road, the total cost of modifying the road is

| A 1 - B 1| + | A 2 - B 2| + ... + | AN - BN |

Please compute the minimum cost of grading his road so it becomes a continuous slope. FJ happily informs you that signed 32-bit integers can certainly be used to compute the answer.

Input

* Line 1: A single integer: N
* Lines 2..N+1: Line i+1 contains a single integer elevation: Ai

Output

* Line 1: A single integer that is the minimum cost for FJ to grade his dirt road so it becomes nonincreasing or nondecreasing in elevation.

Sample Input

7
1
3
2
4
5
3
9

Sample Output

3

题意:

将数组a变成递增或递减序列,按照图中的公式进行计算所得到的最小代价。

思路:首先要明确,由于数组的值太大,所以仔细一想,转化后的每个数一定是之前a【】就出现过的。这样就可以简化枚举的个数。

首先考虑不减的情况:

dp[i][j]代表到了第i个数,当前最大值是j,的最小代价,转移方程:dp【i】【j】=abs(a[i]-b[j]) + min(dp【i-1】【k】(k<=j))

然后考虑不增的情况,

dp[i][j]代表到了第i个数,当前最小值是j,的最小代价,转移方程:dp【i】【j】=abs(a[i]-b[j]) + min(dp【i-1】【k】(k>=j))

但是发现好多代码只考虑第一种就过了,不知道是不是样例水???

代码:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<memory.h>
using namespace std;
const int INF=0x3f3f3f3f;

int a[2010],b[2010];
int dp[2010][2010];
int dpp[2010][2010];
int cmp(int a,int b){
    return a>b;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    memset(dp,INF,sizeof(dp));

    for(int i=1;i<=n;i++){
        dp[0][i]=0;
    }
    int lala=INF;
    int minn;
    for(int i=1;i<=n;i++){
        minn=INF;
        for(int j=1;j<=n;j++){
            ///dp[i][j]=min(dp[i][j],dp[i-1][j]+abs(a[i]-b[j]));
            minn = min(dp[i-1][j],minn);
                dp[i][j] = minn+abs(a[i]-b[j]);
         //   cout<<i<<" "<<j<<"  :"<<dp[i][j]<<endl;
            if(i==n){
                lala=min(lala,dp[i][j]);
            }
        }
    }
     memset(dp,INF,sizeof(dp));

    for(int i=1;i<=n;i++){
        dp[0][i]=0;
    }
    sort(b+1,b+1+n,cmp);
    int haha=INF;
    for(int i=1;i<=n;i++){
        minn=INF;
        for(int j=1;j<=n;j++){
            ///dp[i][j]=min(dp[i][j],dp[i-1][j]+abs(a[i]-b[j]));
            minn = min(dp[i-1][j],minn);
                dp[i][j] = minn+abs(a[i]-b[j]);
         //   cout<<i<<" "<<j<<"  :"<<dp[i][j]<<endl;
            if(i==n){
                haha=min(lala,dp[i][j]);
            }
        }
    }
    cout<<min(haha,lala)<<endl;
}
/*

*/

poj1745

http://poj.org/problem?id=1745

Divisibility

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 13930   Accepted: 4936

Description

Consider an arbitrary sequence of integers. One can place + or - operators between integers in the sequence, thus deriving different arithmetical expressions that evaluate to different values. Let us, for example, take the sequence: 17, 5, -21, 15. There are eight possible expressions: 17 + 5 + -21 + 15 = 16
17 + 5 + -21 - 15 = -14
17 + 5 - -21 + 15 = 58
17 + 5 - -21 - 15 = 28
17 - 5 + -21 + 15 = 6
17 - 5 + -21 - 15 = -24
17 - 5 - -21 + 15 = 48
17 - 5 - -21 - 15 = 18
We call the sequence of integers divisible by K if + or - operators can be placed between integers in the sequence in such way that resulting value is divisible by K. In the above example, the sequence is divisible by 7 (17+5+-21-15=-14) but is not divisible by 5.

You are to write a program that will determine divisibility of sequence of integers.

Input

The first line of the input file contains two integers, N and K (1 <= N <= 10000, 2 <= K <= 100) separated by a space.
The second line contains a sequence of N integers separated by spaces. Each integer is not greater than 10000 by it's absolute value.

Output

Write to the output file the word "Divisible" if given sequence of integers is divisible by K or "Not divisible" if it's not.

Sample Input

4 7
17 5 -21 15

Sample Output

Divisible

Source

Northeastern Europe 1999

题意:就是给了n个数字,问可加可减,每个数字必须算一次,最终能否被k整除。

思路:

看到k这么小,直接递推就好。注意mod负数就好。

代码:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<memory.h>
using namespace std;
const int INF=0x3f3f3f3f;
int a[10010];
int dp[10010][110];
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    dp[1][((a[1])%k+k)%k]=1;
    dp[1][((-a[1])%k+k)%k]=1;
    for(int i=2;i<=n;i++){
        for(int j=0;j<=k;j++){
            if(dp[i-1][((j-a[i])%k+k)%k]==1 || dp[i-1][((j+a[i])%k+k)%k]==1)
                dp[i][j]=1;
        }
    }
    /// cout<<"&*&*"<<endl;
    if(dp[n][0]==1)
        printf("Divisible\n");
    else
        printf("Not divisible\n");

    return 0;
}

poj3616

http://poj.org/problem?id=3616

Milking Time

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 15223   Accepted: 6450

Description

Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that she decides to schedule her next N (1 ≤ N ≤ 1,000,000) hours (conveniently labeled 0..N-1) so that she produces as much milk as possible.

Farmer John has a list of M (1 ≤ M ≤ 1,000) possibly overlapping intervals in which he is available for milking. Each interval i has a starting hour (0 ≤ starting_houriN), an ending hour (starting_houri < ending_houriN), and a corresponding efficiency (1 ≤ efficiencyi ≤ 1,000,000) which indicates how many gallons of milk that he can get out of Bessie in that interval. Farmer John starts and stops milking at the beginning of the starting hour and ending hour, respectively. When being milked, Bessie must be milked through an entire interval.

Even Bessie has her limitations, though. After being milked during any interval, she must rest R (1 ≤ RN) hours before she can start milking again. Given Farmer Johns list of intervals, determine the maximum amount of milk that Bessie can produce in the N hours.

Input

* Line 1: Three space-separated integers: N, M, and R
* Lines 2..M+1: Line i+1 describes FJ's ith milking interval withthree space-separated integers: starting_houri , ending_houri , and efficiencyi

Output

* Line 1: The maximum number of gallons of milk that Bessie can product in the N hours

Sample Input

12 4 2
1 2 8
10 12 19
3 6 24
7 10 31

Sample Output

43

Source

USACO 2007 November Silver


题意:

就是给了工作的开始结束时间,给了一定的val,问怎么工作val最大。

思路:按照结束时间从小到大排序,然后dp【i】代表前i段的最大val。每一段都是从可以推到他的(就是dp【k】+t<=dp[i].begin)的一段找最大的val。

代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int mod=100000007;
typedef long long LL;
struct node{
    int beg;
    int endd;
    int val;
}a[1010];
int cmp(node b,node c){
    return b.endd<c.endd;
}
int dp[1010];
int main()
{
  int n,m,t;
  int maxx=0;
  scanf("%d%d%d",&n,&m,&t);
  for(int i=1;i<=m;i++){
    scanf("%d%d",&a[i].beg,&a[i].endd);
    scanf("%d",&a[i].val);
  }
  int lala;
  sort(a+1,a+1+m,cmp);
  for(int i=1;i<=m;i++){
    dp[i]=a[i].val;
    lala=0;
    for(int j=1;j<i;j++){
        if(a[j].endd+t<=a[i].beg)
        {
            lala=max(lala,dp[j]);
        }
    }
    dp[i]+=lala;
    maxx=max(maxx,dp[i]);
  }
  cout<<maxx<<endl;
}
/*
12 4 2
1 2 8
3 6 24
7 10 31
10 12 19

*/
发布了565 篇原创文章 · 获赞 110 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/xianpingping/article/details/88586270