Kuangbin takes you to the basic DP project

Keywords: PHP

There are so many DP projects of bin God. I'll sort out the basic DP projects I've done.

HDU1029 Ignatius and the Princess IV

http://acm.hdu.edu.cn/showproblem.php?pid=1029

meaning of the title

Give n, and N numbers, and find the number that appears at least (n+1)/2 times.

thinking

At least (n+1)/2 times, if this number exists, it must be the special number in the middle after sorting.

HDU1069 Monkey and Banana

http://acm.hdu.edu.cn/showproblem.php?pid=1069

meaning of the title

A monkey has to stack boxes to get the bananas hanging high. Now give n types of boxes, and the length, width and height of these boxes, one type of box can have countless, the length and width of the box on the top must be strictly smaller than the box on the bottom. For example, if there is a box with a height of 10,2030, we can put the box with a height of 10,2030 at the bottom of 30 on the box with a height of 20,230 at the bottom of 10. The maximum height that the output stack box can reach is required.

thinking

Before you write this question, let's look at the longest path of any starting point in a directed acyclic graph. dp[i] represents the longest path length that can be reached from point I. It is easy to think that dp[i]=max(dp[j]+maps[i][j],dp[i]),j is the next node of point I. The implementation code is as follows:

int DP(int m,int n){
    if(dp[m]>0)return dp[m];
    for(int i=1;i<=n;i++){
        if(maps[m][i]!=INF){
            dp[m]=max(dp[m],DP(i,n)+maps[m][i]);
        }
    }
    return dp[m];
}

The classical rectangular nesting problem is solved by the longest path. The problem of rectangular nesting is to find the maximum number of rectangles that can be nested by giving the lengths and widths of several rectangles. If each rectangle is regarded as a point on a digraph, two rectangles that can be nested form a directed edge between the two points, and the edge weight is 1, the longest edge of any starting point of a digraph can be obtained, then the maximum value can be found. The problem of Monkey and Banana is the deformation of rectangle nesting, which decomposes a cube into rectangles with point weights, and then uses rectangle nesting to find the path with maximum point weights. The code is as follows:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int MAXN=100;
const int INF=0x3f3f3f3f;
int maps[MAXN][MAXN];
int point[MAXN];
struct rect{
    int l,w;
    int h;
};
rect re[MAXN];
long long dp[MAXN];
long long DP(int m,int n){
    if(dp[m]>0)return dp[m]+point[m];
    for(int i=1;i<n;i++){
        if(maps[m][i]==0){
            dp[m]=max(dp[m],DP(i,n));
        }
    }
    return dp[m]+point[m];
}
int main(){
    int n;
    int flag=1;
    while(cin>>n&&n){
        int a[5];
        int k=1;
        for(int i=0;i<MAXN;i++){
            dp[i]=0;
        }
        memset(maps,INF,sizeof(maps));
        for(int i=1;i<=n;i++){
            cin>>a[0]>>a[1]>>a[2];
            sort(a,a+3);
            if(a[0]==a[1]&&a[1]==a[2]){
                re[k].l=a[0];re[k].w=a[1];re[k].h=a[2];
                k++;
            }
            else if(a[0]==a[1]){
                re[k].l=a[0];re[k].w=a[1];re[k].h=a[2];
                k++;
                re[k].l=a[2];re[k].w=a[0];re[k].h=a[1];
                k++;
            }
            else if(a[1]==a[2]){
                re[k].l=a[1];re[k].w=a[2];re[k].h=a[0];
                k++;
                re[k].l=a[1];re[k].w=a[0];re[k].h=a[2];
                k++;
            }
            else {
                re[k].l=a[1];re[k].w=a[0];re[k].h=a[2];
                k++;
                re[k].l=a[2];re[k].w=a[1];re[k].h=a[0];
                k++;
                re[k].l=a[2];re[k].w=a[0];re[k].h=a[1];
                k++;
            }
        }
        for(int i=1;i<k;i++){
            for(int j=1;j<k;j++){
                if(i==j)continue;
                if(re[i].l<re[j].l&&re[i].w<re[j].w){
                    if(maps[i][j]!=0){
                        maps[i][j]=0;
                    }
                }
            }
            point[i]=re[i].h;
        }
        long long maxnum=-1;
        for(int i=1;i<k;i++){
            maxnum=max(maxnum,DP(i,k));
        }
        cout<<"Case "<<flag<<": maximum height = "<<maxnum<<endl;
        flag++;
    }
    return 0;
}

HDU 1084 What Is Your Grade

http://acm.hdu.edu.cn/showproblem.php?pid=1084

meaning of the title

Now there are five questions. If you finish all of them, you can get full marks. If you don't finish one question, you can only get 50 points. If you do four questions, you may get 95 points or 90 points. It depends on whether you are the first half of all the students who finish four questions. Yes, 95 points, or 90 points. And so on.

thinking

Sand sculpture, let's not talk more about it.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int MAXN=110;
struct students{
    int num;
    int hour,minn,sec;
};
students stu[MAXN];
int score[]={50,60,70,80,90,100};
int main(){
    int n;
    while(cin>>n&&n!=-1){
        for(int i=1;i<=n;i++){
            scanf("%d %d:%d:%d",&stu[i].num,&stu[i].hour,&stu[i].minn,&stu[i].sec);
        }
        for(int i=1;i<=n;i++){
            int ans=0,sum=1,itemp=stu[i].hour*3600+stu[i].minn*60+stu[i].sec;
            if(stu[i].num==5||stu[i].num==0){
                cout<<score[stu[i].num]<<endl;
                continue;
            }
            for(int j=1;j<=n;j++){
                if(i==j)continue;
                int jtemp=stu[j].hour*3600+stu[j].minn*60+stu[j].sec;
                if(stu[i].num==stu[j].num){
                        if(jtemp<itemp){
                            ans++;
                        }
                        sum++;
                }
            }
                if(ans>=sum/2){
                    cout<<score[stu[i].num]<<endl;
                }
                else cout<<score[stu[i].num]+5<<endl;
        }
        cout<<endl;
    }
    return 0;
}

HDU1114 Piggy-Bank

http://acm.hdu.edu.cn/showproblem.php?pid=1114

meaning of the title

Give a pig a piggy bank the weight when it's empty. The piggy bank contains the weight of some coins. Given the value and weight of several types of coins, coins can be withdrawn indefinitely, eventually making the piggy can reach the specified weight, and the value of coins is minimal.

thinking

A very naked complete backpack, but generally find the value of large, this time find the value of small... To determine whether a preferable scheme can achieve the specified weight, it is only necessary to determine whether it is equal to the initialization value.

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int MAXN=1e5+100;
typedef long long ll;
const int INF=9999999;
int v[MAXN];
int w[MAXN];
ll dp1[MAXN],dp2[MAXN];
int main(){
    int t;
    cin>>t;
    while(t--){
        int n,pig,weight;
        cin>>pig>>weight>>n;
        for(int i=1;i<=n;i++){
            cin>>v[i]>>w[i];
        }
        for(int i=0;i<MAXN;i++){
            dp1[i]=INF;dp2[i]=INF;
        }
        for(int i=1;i<=n;i++){
            dp1[0]=0;
            for(int j=1;j<w[i];j++){
                dp1[j]=dp2[j];
            }
            for(int j=w[i];j<=weight-pig;j++){
                dp1[j]=min(dp2[j],dp1[j-w[i]]+v[i]);
            }
            for(int j=1;j<=weight-pig;j++){
                dp2[j]=dp1[j];
            }
        }
        if(dp1[weight-pig]!=INF)cout<<"The minimum amount of money in the piggy-bank is "<<dp1[weight-pig]<<"."<<endl;
        else cout<<"This is impossible."<<endl;
    }
    return 0;
}

HDU1176 Free Pie

thinking

dp[j][i], which represents the number of pies obtained at the first second of the jth position. The state transition equation is dp[j][i]=max(dp[j+1][i+1],dp[j-1][i+1],dp[j][i+1]), that is, for the current position, the current time must be transferred by the optimal solution of the left and right and the last second of the current position.

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>


using namespace std;
const int MAXN=1e5+10;
long long dp[15][MAXN];
struct nodes{
    int x,t;
};
nodes num[MAXN];
int main(){
    int n;
    while(scanf("%d",&n)!=EOF&&n){
        int maxtime=-1;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++){
            scanf("%d%d",&num[i].x,&num[i].t);
            dp[num[i].x][num[i].t]++;
            maxtime=max(maxtime,num[i].t);
        }
        for(int i=maxtime-1;i>=0;i--){
            for(int j=0;j<=10;j++){
                long long temp;
                if(j-1>=0&&j+1<=10){
                    temp=max(max(dp[j-1][i+1],dp[j+1][i+1]),dp[j][i+1]);
                }
                else if(j==0){
                    temp=max(dp[j][i+1],dp[j+1][i+1]);
                }
                else if(j==10){
                    temp=max(dp[j][i+1],dp[j-1][i+1]);
                }
                dp[j][i]+=temp;
            }
        }
        printf("%lld\n",dp[5][0]);
    }
    return 0;
}

 

 

 

 

Posted by hemantraijain on Tue, 23 Apr 2019 12:03:34 -0700