CCF认证-201809-4
思路:没有很好的思路,就暴力了拿了70分,还没有满分,还会再更新的。
问题描述
试题编号: | 201809-4 |
试题名称: | 再卖菜 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这些商店都卖一种蔬菜。 输入格式 输入的第一行包含一个整数n,表示商店的数量。 输出格式 输出一行,包含n个正整数,依次表示每个商店第一天的菜价。 样例输入 8 样例输出 2 2 2 1 6 5 16 10 数据规模和约定 对于30%的评测用例,2<=n<=5,第二天每个商店的菜价为不超过10的正整数; |
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn=310;
int flag,n;
int a[maxn],b[maxn],ans[maxn];
void p(int t[])
{
printf("%d",t[0]);
for(int i=1;i<n-1;i++)
printf(" %d",t[i]);
printf(" %d\n",t[n-1]);
}
//超时了---记忆化搜索/差分约束
void dfs(int u,int t[])
{
if(flag) return;
if(u==n)
{
if((t[u-1]+t[u-2])/2==a[u-1])
{
for(int i=0;i<n;i++)
ans[i]=t[i];
flag=1;return;
}
}
int len,s;
if(u==1)
{
s=a[u-1]*2-t[u-1];
len=(a[u-1]+1)*3-t[u-1];
if(len<=0) return;
}//当前的最小与最大的要求
else
{
s=a[u-1]*3-t[u-1]-t[u-2];
len=(a[u-1]+1)*3-t[u-1]-t[u-2];
if(len<=0) return;
}
if(s<=0) s=1;
for(int i=s;i<len;i++)
{
t[u]=i;
if(u!=n-1&&t[u]>=a[u]*3) return;
else if(u==n-1&&(t[u]+t[u-1])/2>a[u]) return;//稍微剪枝一下
dfs(u+1,t);
}
}
int main()
{
flag=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=1;i<(a[0]+1)*2;i++)
{ b[0]=i;dfs(1,b);if(flag) break;}
p(ans);
return 0;
}