HUNAU—exercise3_动态规划

来源:互联网 发布:手机上安装linux 编辑:程序博客网 时间:2024/06/05 06:14

HDU 1231  最大连续子序列

求最长连续子序列的和
#include<cstdio>#include<iostream>#include<stdlib.h>#include<algorithm>#include<queue>using namespace std;#define M 10002#define INF 1<<29int a[M],n;void solve(){    int sum=0,big=-INF;    int j=0,first=0,last=0;    for(int i=0;i<n;i++)    {        sum+=a[i];        if(big<sum)        {            first=j;            last=i;            big=sum;        }        if(sum<0)        {            j=i+1;            sum=0;        }    }    if(big<0){big=0;first=0,last=n-1;}    printf("%d %d %d\n",big,a[first],a[last]);}int main(){    while(~scanf("%d",&n))    {        if(n==0)break;        for(int i=0;i<n;i++)        scanf("%d",&a[i]);        solve();    }    return 0;}

HDU 1864 最大报销额
该题要注意的就是每张单子A种类的总和不能大与600,同样B,C类也一样,刚开始我就错了这里,还有注意如果不是A,B,C类的不可以报销;
该题就是要把浮点型变成整数这样才能用01背包,这里就只要乘以100就可以了。

#include<cstdio>#include<iostream>#include<stdlib.h>#include<algorithm>#include<cstring>using namespace std;#define N 3000022#define INF 1<<29//2689int cost[30];//支票张数int dp[N];int v;int main(){    int m,n,cnt;    double temp;    char ch;    int ta,tb,tc;    while(scanf("%lf%d",&temp,&n)==2)    {        if(n==0)break;        v=(int)(temp*100);        cnt=0;        for(int k=0; k<n; k++)        {            scanf("%d",&m);            int flag=0;            ta=tb=tc=0;            for(int i=0; i<m; i++)            {                getchar();                ch=getchar();                getchar();                scanf("%lf",&temp);                if(flag==0)                {                    if(ch=='A')                        ta+=(int)(temp*100);                    else if(ch=='B')                        tb+=(int)(temp*100);                    else if(ch=='C')                        tc+=(int)(temp*100);                    else                       flag=1;                    if(ta>60000||tb>60000||tc>60000)                        flag=1;                }            }            /*for(int i=0;i<M;i++)              printf("%lf ",a[i]);*/            int sum=ta+tb+tc;            if(flag==0&&sum<=100000)            {                cost[cnt++]=sum;            }        }        memset(dp,0,sizeof(dp));        for(int i=0; i<cnt; i++)            for(int j=v; j>=cost[i]; j--)                dp[j]=max(dp[j],dp[j-cost[i]]+cost[i]);        printf("%.2lf\n",(double)(dp[v]/100.0));    }    return 0;}

HDU1506 Largest Rectangle in a Histogram

思路:从前向后扫描一遍,当遇到前面比它高的矩形停下来结算,否则一直将矩形加入单调队列,注意新增虚拟首尾矩形,高度均为0;


#include<cstdio>#include<iostream>#include<cstring>using namespace std;#define M 100002#define INF 1<<29struct rect{    int left;//左边界    int h;//高度} a[M];int Q[M];int main(){    int i,n;    while(scanf("%d",&n)==1&&n!=0)    {        for(i=1; i<=n; i++)        {            scanf("%d",&a[i].h);            a[i].left=i;        }        a[0].left=a[0].h=0;        n++;        a[n].left=n;        a[n].h=0;        long long largest=0,area;        int rear=0;        Q[rear++]=0;        for(i=1; i<=n; i++)        {            if(a[i].h>=a[Q[rear-1]].h)                Q[rear++]=i;            else            {   //一旦发现前面有比我高的就结算                //直到左边找不到比它高的                while(rear>0&&a[i].h<a[Q[rear-1]].h)                {                    area=(long long)(i-a[Q[rear-1]].left)*a[Q[rear-1]].h;                    if(largest<area)largest=area;                    rear--;                }                //更新第i个矩形的左边起点,并加入队列                a[i].left=a[Q[rear]].left;                Q[rear++]=i;            }        }        printf("%I64d\n",largest);    }    return 0;}

















0 0
原创粉丝点击