http://poj.org/problem?id=2586
大意是一个公司在12个月中,或固定盈余s,或固定亏损d.
但记不得哪些月盈余,哪些月亏损,只能记得连续5个月的代数和总是亏损(<0为亏损),问全年是否可能盈利?若可能,输出可能最大盈利金额,否则输出“Deficit".
枚举即可过
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
int a,b,c[15],max1;
void bu(int n,int m)
{
int i,m1;
if (n==13)
{
int sum=0;
for (i=1;i<=12;i++) sum+=c[i];
if (sum>max1) max1=sum;
return ;
}
c[n]=a;
m1=m;//这里要将m复原否则会出错
if (n>=5)
{
m+=c[n];
m-=c[n-5];
if (m<0) bu(n+1,m);
}
else
{
m+=c[n];
bu(n+1,m);
}
m=m1;
c[n]=b;
if (n>=5)
{
m+=c[n];
m-=c[n-5];
if (m<0) bu(n+1,m);
}
else
{
m+=c[n];
bu(n+1,m);
}
return ;
}
int main()
{
freopen("a","r",stdin);
c[0]=0;
while (scanf("%d%d",&a,&b)!=EOF)
{
max1=-100;
b=-b;
bu(1,0);
if (max1<0) printf("Deficit\n");
else printf("%d\n",max1);
}
return 0;
}
贪心算法:计算出5个月中要使这5个月亏本至少要有几个月是亏本,设为k。然后按以下规则贪心:对于每个连续的5个月,把k个月安排为亏本,把(5-k)个月安排为盈利。同时,在不与前面已确定好的月份盈亏情况矛盾的情况下,尽量把亏本的月份安排向后排。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#define N 50100
using namespace std;
int main()
{
//freopen("a","r",stdin);
int a,b,i,j,k,c[20];
while (scanf("%d%d",&a,&b)!=EOF)
{
for (k=1;k<=5;k++) if (k*b>(5-k)*a) break;
for (i=1;i<=12;i++) c[i]=0;
/*for (i=1;i<=8;i++)
{
int count=0;
for (j=i;j<=i+4;j++)
if (c[j]==b) count++;
else if (c[j]==0)
{
int j1;
for (j1=j;j1<=i+4;j1++) c[j1]=a;
for (j1=k-count;j1>=1;j1--) c[i+4-j1+1]=b;
break;
}
}*/
for (i=1;i<=5-k;i++) c[i]=a;
for (i=5-k+1;i<=5;i++) c[i]=b;
for (i=6;i<=12;i++)
{
int count=0;
for (j=i-4;j<=i-1;j++) if (c[j]==b) count++;
if (count<k) c[i]=b;
else c[i]=a;
}
int sum=0;
for (i=1;i<=12;i++)
if (c[i]==a) sum+=c[i];
else sum-=c[i];
if (sum<0) printf("Deficit\n");
else printf("%d\n",sum);
}
return 0;
}