洛谷 P2392 kkksc03考前临时抱佛脚(dfs,排序优化

洛谷 P2392 kkksc03考前临时抱佛脚(dfs,排序优化

洛谷 P2392 kkksc03考前临时抱佛脚

洛谷 P2392 kkksc03考前临时抱佛脚(dfs,排序优化_第1张图片

这题dalao用dp,本蒟蒻只会搜索/哭
对于每一科,只要找到任意个习题册,使其所耗费的时间大于等于总时间的一半,这些任意个习题册所花费的最小时间就是该科的最小时间。
也就是在m个习题册中搜n个习题册~
写一个很简单的dfs

void dfs(int s,int n,int m){//s为和,n为当前位置,m为总位置
    if(n==m) return;//到了最后一个
    if(flag[n]==1) return; //搜过
    if(2*(s+k[n])>=sum){  //大于等于总数的二分之一
        min1=min(min1,s+k[n]);
        return;
    } 
    int i;
    for(i=n+1;i<m;i++){  //搜剩下的
        flag[n]=1;
        dfs(s+k[n],i,m);
        flag[n]=0;
    }
}

ps:先排序,这样就不用搜前面的数,不然会T

喜闻乐见的完整代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define ll long long
using namespace std;

int ans=0,sum,min1;
int num[4];
int k[30],flag[30];

void dfs(int s,int n,int m){//s为和,n为当前位置,m为总位置
    if(n==m) return;//到了最后一个
    if(flag[n]==1) return; //搜过
    if(2*(s+k[n])>=sum){  //大于等于总数的二分之一
        min1=min(min1,s+k[n]);
        return;
    }
    int i;
    for(i=n+1;i<m;i++){  //搜剩下的
        flag[n]=1;
        dfs(s+k[n],i,m);
        flag[n]=0;
    }
}

int main(){
    int i,a;
    for(i=0;i<4;i++) cin>>num[i];
    for(i=0;i<4;i++){
        sum=0;
        for(a=0;a<num[i];a++){
            cin>>k[a];
            sum+=k[a];
            flag[a]=0;
        }
        sort(k,k+num[i]);
        min1=sum;
        for(a=0;a<num[i];a++) {
            dfs(0,a,num[i]);
        }
        ans+=min1;
    }
    cout<<ans;
}

你可能感兴趣的:(洛谷 P2392 kkksc03考前临时抱佛脚(dfs,排序优化)