USACO fence8 4.1.2

来源:互联网 发布:彩虹代刷网源码2.0 编辑:程序博客网 时间:2024/06/05 22:31

这个题好难我看了题解的,迭代搜索和二分法。

#include <stdio.h>#include <stdlib.h>#include<string.h>int boardnum;int railnum;int board[60]={0};int rail[1050]={0};int waste[1050]={0};int check;int sum,total;int max;/*==========================sort===========================*/void sort(int *a,int n){    int i ,j,t;    for(i=0;i<n-2;i++)        for(j=1;j<=n-1-i;j++)        {            if(a[j]>a[j+1])            {                t=a[j];                a[j]=a[j+1];                a[j+1]=t;            }        }}void dfs(int key, int start){    int i ,sum=0;    int num;    if(!key)       check=1;    if(check==1)       return;    for(i=1;i<=boardnum;i++)    {        if(board[i]<rail[1])        {            sum+=board[i];        }    }    if(sum>max)                                         //对于切剩下的board(无法再切下rail),统计一下总和。      return;                                                 //如果这个值大于board长度的总和减去rail长度的总和,一定无解,可以剪枝   for(i=start;i<=boardnum;i++)    {        if(board[i]>=rail[key])        {            if(rail[key]==rail[key-1]&&key>1)                   num=i;                                 //rail[i+1]=rail[i],则rail[i+1]对应的board一定大于等于rail[i]对应的board            else               num=1;            board[i]-=rail[key];            dfs(key-1,num);            board[i]+=rail[key];        }    }    return;}int main(){    FILE *fin=fopen("fence8.in","r");    FILE *fout=fopen("fence8.out","w");    int i ,j;    int ans=0;    int mid,low,high;    fscanf(fin,"%d",&boardnum);    for(i=1;i<=boardnum;i++)    {        fscanf(fin,"%d",&board[i]);        total+=board[i];    }    fscanf(fin,"%d",&railnum);    for(i=1;i<=railnum;i++)        fscanf(fin,"%d",&rail[i]);    sort(board,boardnum);    sort(rail,railnum);    for(i=1;i<=railnum;i++)        waste[i]=waste[i-1]+rail[i];    low=0;    high=railnum;    while(low<=high)                        //二分法    {        check=0;        mid=(low+high)/2;        max=total-waste[mid];        dfs(mid,1);                                  //迭代搜索就是说确定搜索的层数        if(check)                                      //将问题转化为n个木头能否切成k块木板        {            ans=mid;            low=mid+1;        }        else           high=mid-1;    }    fprintf(fout,"%d\n",ans);    return 0;}


原创粉丝点击