poj 1513 Scheduling Lectures

来源:互联网 发布:asp源码 自助建站 编辑:程序博客网 时间:2024/06/05 02:37

题目链接:http://poj.org/problem?id=1513

题目大意及思路:求将n个topic,分配到lecture中,使lecture数尽量小,然后使不满意度最小,先贪心求得最少lecture数,再dp,dp前先预处理出每一段的界,这样可以大大缩短时间。我的从500ms优化到16ms.

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<string>#include<queue>#include<algorithm>#include<vector>#include<stack>#include<list>#include<iostream>#include<map>using namespace std;#define inf 0x3f3f3f3f#define Max 110int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a<b?a:b;}int dp[1100][1100],L,C,n;int c[1100][1100];int a[1100],sum[1100];int up[1100],low[1100];int rec;int num;int main(){    int i,count=1,j,k;    while(scanf("%d",&n),n)    {        scanf("%d%d",&L,&C);        num=0;sum[0]=0;        int tmp=0;        for(i=1;i<=n;i++)        {            scanf("%d",&a[i]);            sum[i]=sum[i-1]+a[i];            if(sum[i]-sum[tmp]>L)            {                num++;                tmp=i-1;                up[num]=tmp;              //  printf("tmp %d\n",tmp);            }        }        num++;        up[num]=n;        tmp=n;        rec=num;        low[num]=n;        for(i=n-1;i>=0;i--)        {            if(sum[tmp]-sum[i]>L)            {                tmp=i+1;                rec--;             //   printf("rec %d low %d\n",rec,tmp+1);                low[rec]=i+1;            }        }       // printf("%d\n",num);        for(i=1;i<=num;i++)        {          //  printf("up %d low %d\n",up[i],low[i]);            for(j=low[i];j<=up[i];j++)            {                dp[i][j]=inf;                if(i==1)                {                    dp[i][j]=0;                    if(L-sum[j]>=1&&L-sum[j]<=10)                        dp[i][j]-=C;                    else if(L-sum[j]>10)                        dp[i][j]+=(L-sum[j]-10)*(L-sum[j]-10);                 //   printf("i %d j %d dp %d\n",i,j,dp[i][j]);                    continue;                }                for(k=(up[i-1]<j-1)?up[i-1]:j-1;sum[j]-sum[k]<=L&&k>=low[i-1];k--)                {                   // if(dp[i-1][k]==inf)                     //   continue;                    tmp=0;                    if(L-(sum[j]-sum[k])>=1&&L-(sum[j]-sum[k])<=10)                    tmp-=C;                    else if(L-(sum[j]-sum[k])>10)                    tmp+=(L-(sum[j]-sum[k])-10)*(L-(sum[j]-sum[k])-10);                    dp[i][j]=min(dp[i][j],dp[i-1][k]+tmp);                   //  printf("i %d j %d k %d dp %d\n",i,j,k,dp[i][j]);                }            }        }        printf("Case %d:\n\nMinimum number of lectures: %d\nTotal dissatisfaction index: %d\n\n",count++,num,dp[num][n]);    }}


 

原创粉丝点击