您的位置:首页 > 运维架构

WF 1995 Stamps and Envelope Size (uvaLive 5181 )

2016-04-11 23:31 232 查看
一个背包问题,并不难,难道是WF的签到?

输出说明:注意用%3d,最大连续邮资取最大的,若相等,取邮票种类最少的,若相等,取最大面值最小的。

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;

#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)

#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;
const int maxn=10 ;
const int maxV=10000 ;

int S,n;
int num;
bool dp[12][maxV+3];
int a[110],V;

struct ANS
{
int maxi,num;
int b[110];
void init()
{
maxi=-1;
}
void update(ANS c)
{
if(maxi<c.maxi)
{
maxi=c.maxi;
num=c.num;
for(int i=1;i<=c.num;i++)
{
b[i]=c.b[i];
}
return;
}
if(maxi>c.maxi) return;
if(num>c.num)
{
maxi=c.maxi;
num=c.num;
for(int i=1;i<=c.num;i++)
{
b[i]=c.b[i];
}
return;
}
if(num<c.num) return;

if( b[num]>c.b[num] )
{
maxi=c.maxi;
num=c.num;
for(int i=1;i<=c.num;i++)
{
b[i]=c.b[i];
}
return;
}

}

} ans,tmp;

bool cmp(int x,int y)
{
return x>y;
}
void work()
{
memset(dp,0,sizeof dp);
dp[0][0]=1;
for(int i=1;i<=S;i++)
{
for(int v=0;v<=V;v++)
{
for1(k,num) if(v>=a[k] )
{
dp[i][v]|=dp[i-1][v-a[k]];
}
}
}
int v;
for( v=1;v<=V+1;v++)
{
bool ok=false;
for(int i=0;i<=S;i++)
{
if(dp[i][v]) {ok=true;break;}
}
if(!ok) break;
}

tmp.maxi=--v;
tmp.num=num;
for(int i=1;i<=num;i++)
{
tmp.b[i]=a[i];
}
ans.update(tmp);

}
int main()
{
while(~scanf("%d",&S)&&S)
{
scanf("%d",&n);
ans.init();
for1(i,n)
{
V=0;
scanf("%d",&num);
int maxi=0;
for1(j,num)
{
scanf("%d",&a[j]);
maxi=max(maxi,a[j]);
}
sort(a+1,a+1+num);
V=maxi*S;
work();
}
printf("max coverage = %3d :",ans.maxi);
for(int i=1;i<=ans.num;i++)
{
printf("%3d",ans.b[i]);
}
putchar('\n');
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: