HDU 1231 最大连续子序列
求最长连续子序列的和
#include<cstdio>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
#include<queue>
using namespace std;
#define M 10002
#define INF 1<<29
int 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;
}
该题要注意的就是每张单子A种类的总和不能大与600,同样B,C类也一样,刚开始我就错了这里,还有注意如果不是A,B,C类的不可以报销;
该题就是要把浮点型变成整数这样才能用01背包,这里就只要乘以100就可以了。
HDU1506 Largest Rectangle in a Histogram
思路:从前向后扫描一遍,当遇到前面比它高的矩形停下来结算,否则一直将矩形加入单调队列,注意新增虚拟首尾矩形,高度均为0;
该题就是要把浮点型变成整数这样才能用01背包,这里就只要乘以100就可以了。
#include<cstdio>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 3000022
#define INF 1<<29
//2689
int 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;
}
思路:从前向后扫描一遍,当遇到前面比它高的矩形停下来结算,否则一直将矩形加入单调队列,注意新增虚拟首尾矩形,高度均为0;
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define M 100002
#define INF 1<<29
struct 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;
}