Education Reform(CodeForces-119C)[DP]

 

The meaning of problems: m is selected from the discharged to the n n days course, one day, difficult to be incremented, corresponding to a job for each course amounts Xi, and Xi = Xi-1 + k or Xi - Xi-1 * k The total amount of work to be as large as possible, and asked whether the arrangement, if the arrangement, seeking scheme.

Ideas: an attempt to storm the game with DFS search, but unfortunately time out, try a variety of optimization without success, after the game looked Interpretations know that this is DP, also found that many search solutions can be used when the subject if the DP will save a lot of time !

  DP establish a three-dimensional array, dp [i] [j] [k], i denotes the i-th day, j denotes the i-th row j-th day course, k represents an amount of the selected job as the first job j course left end section point + k. Note that where pre array should be established to mark the DP path.

code show as below:

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

struct subject{
    long long a,b;
    int c,id;
    bool operator<(subject& t){
        return c<t.c;
    }
}arr[60];
struct route{
    int addition,id;
    route(){}
    route(int x,int y):id(x),addition(y){}
}pre[60][60][120],ending;

int n,m,k;
long long dp[60][60][120];//day/num/work

bool makeDp(){
    memset(dp,-1,sizeof(dp));
    for(int j=1;j<=m;j++)
        for(long long i=arr[j].a;i<=arr[j].b;i++){
            dp[1][j][i-arr[j].a]=i;
        }
    for(int i=1;i<n;i++){
        for(int j=i;j<=m&&m-j>=n-i;j++){
            for(long long kk=arr[j].a;kk<=arr[j].b;kk++){
                if(dp[i][j][kk-arr[j].a]==-1)
                    continue;
                for(int jj=j+1;jj<=m;jj++){
                    if(arr[jj].c==arr[j].c)
                        continue;
                    if(k*kk>=arr[jj].a&&k*kk<=arr[jj].b){
                        if(dp[i+1][jj][k*kk-arr[jj].a]<dp[i][j][kk-arr[j].a]+k*kk){
                            dp[i+1][jj][k*kk-arr[jj].a]=dp[i][j][kk-arr[j].a]+k*kk;
                            pre[i+1][jj][k*kk-arr[jj].a]=route(j,kk-arr[j].a);
                        }
                    }
                    if(k+kk>=arr[jj].a&&k+kk<=arr[jj].b){
                        if(dp[i+1][jj][k+kk-arr[jj].a]<dp[i][j][kk-arr[j].a]+k+kk){
                            dp[i+1][jj][k+kk-arr[jj].a]=dp[i][j][kk-arr[j].a]+k+kk;
                            pre[i+1][jj][k+kk-arr[jj].a]=route(j,kk-arr[j].a);
                        }
                    }
                }
            }   
        }
    }
    long long flag=-1;
    for(int i=n;i<=m;i++){
        for(long long j=arr[i].a;j<=arr[i].b;j++){
            if(flag<dp[n][i][j-arr[i].a]){
                flag=dp[n][i][j-arr[i].a];
                ending=route(i,j-arr[i].a);
            }
        }
    }
    if(flag!=-1)
        return true;
    return false;
}

void findAns(bool x){
    if(!x)
        cout<<"NO";
    else {
        cout<<"YES\n";
        vector<route> ans;
        route ha=ending;
        for(int i=n;i>=1;i--){
            ans.push_back(ha);
            ha=pre[i][ha.id][ha.addition];
        }
        for(int i=n-1;i>=0;i--){
            cout<<arr[ans[i].id].id<<" "<<arr[ans[i].id].a+ans[i].addition<<endl;
        }
    }
}

int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=m;i++){
        cin>>arr[i].a>>arr[i].b>>arr[i].c;
        arr[i].id=i;
    }
    sort(arr+1,arr+1+m);
    findAns(makeDp());
    return 0;
}
By xxmlala

Guess you like

Origin www.cnblogs.com/xxmlala-fff/p/11617239.html