经典dp——UCF 2016 G

/*
dp[i][j][k]表示到了第i颗子弹,cd1=j,cd2=k 的最优解 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 1005
int cd1,cd2,n,b[N],dp[5][105][105];

int solve(){
    int t,cd=0,ans=0;
    cin>>t;
    for(int i=1;i<=n;i++){
        cd=max(0,cd-(b[i]-b[i-1]));
        if(cd==0)ans++,cd=t;
    }
    return ans;
}

int main(){
    int t;cin>>t;
    for(int tt=1;tt<=t;tt++){
        cin>>n;
        for(int i=1;i<=n;i++)cin>>b[i];
        sort(b+1,b+1+n);
        int J;cin>>J;
        if(J==1){
            printf("Mission #%d: %d\n\n",tt,n-solve());
            continue;
        }
        cin>>cd1>>cd2;
        int cur=1;
        
        memset(dp,0,sizeof dp);
                
        for(int i=0;i<n;i++){
            
            for(int j=0;j<=cd1;j++)
                for(int k=0;k<=cd2;k++)
                    dp[cur][j][k]=0x3f3f3f3f;
                    
            cur^=1;
            for(int j=0;j<=cd1;j++)
                for(int k=0;k<=cd2;k++){
                    int d=b[i+1]-b[i];//下一颗子弹到来时间
                    int x=j-d,y=k-d;//下一颗子弹对应的冷却时间
                    x=max(x,0);y=max(y,0);
                    dp[cur^1][x][y]=min(dp[cur^1][x][y],dp[cur][j][k]+1);//不作为 
                    if(x==0)dp[cur^1][cd1][y]=min(dp[cur^1][cd1][y],dp[cur][j][k]);
                    if(y==0)dp[cur^1][x][cd2]=min(dp[cur^1][x][cd2],dp[cur][j][k]); 
                }
                
        }
        
        int ans=0x3f3f3f3f;
        for(int j=0;j<=cd1;j++)
            for(int k=0;k<=cd2;k++)
                ans=min(ans,dp[cur^1][j][k]);
        printf("Mission #%d: %d\n\n",tt,ans);
    }
} 

 

posted on 2020-03-28 17:07  zsben  阅读(125)  评论(0编辑  收藏  举报

导航