关于这题的另一种思考方法,希望能指点我一下!!!
查看原帖
关于这题的另一种思考方法,希望能指点我一下!!!
184500
hanzhongtlx楼主2020/10/21 16:11

我们假设不零钱可以得到的愤怒值是 sumsum

我们对于每一个选择都可以用 cimod100c_i\bmod 100 元钱减少 (100cimod100)wi(100-c_i\bmod 100 )*w_i 的愤怒值,所以对 (100cimod100)wicimod100\dfrac{(100-c_i\bmod 100 )*w_i} {c_i\bmod 100 } 排序,然后贪心选择即可。

对于开始的钱不能满足的,考虑从选择顺序上倒叙换成零钱,并打上不能用的标记,这个东西应该能用线段树来维护(啊,好吧,我有可能是 sb ,或许不可以)

由于想验证思路正确性,所以打了一个暴力,但是没过,写的应该没问题吧......

请大佬指出纰漏,万分感谢!!!!

下面是暴力的 O(n2)\mathcal O(n^2) 的代码:

#include"algorithm"
#include"iostream"
#include"cstdio"
#include"cmath"
#include"queue"
using namespace std;

#define read(x) scanf("%d",&x)
#define MAXN 100005

int n,m;
struct node
{
	int vis,c,w,le,id;//是否用过,花多少单票,单位愤怒值,剩下多少钱 
}a[MAXN],b[MAXN];
int x;
int sum=0;
priority_queue<pair<int,int> >q;
int ans[MAXN],s[MAXN];

bool cmp(node n,node m){return (100-n.c)*n.w*m.c>(100-m.c)*m.w*n.c;} 

int main()
{
	read(n),read(m);
	for(int i=1;i<=n;i++) read(x),a[i].c=x%100,ans[i]=x/100;
	for(int i=1;i<=n;i++)
	{
		read(x);
		a[i].w=x,a[i].id=i;
		a[i].vis=a[i].le=0;
		b[i]=a[i],sum+=(100-a[i].c)*x;
	}
	sort(b+1,b+n+1,cmp);
	for(int i=1;i<=n;i++) a[b[i].id].id=i;
	for(int i=1;i<=n;i++)
	{
		int op=b[i].id;
		if(a[op].vis) continue;
		int now=0,ne=a[op].c;
		for(int j=op-1;j>=1;j--)
		{
			if(a[j].le==0) continue;
			now+=a[j].le;
			a[j].le=0;
			if(now>=ne){a[j].le=now-ne,ne=0;break;}
		}
		if(!ne){s[op]=1,sum=sum-(100-a[op].c)*a[op].w,a[op].vis=1;continue;}
		if(now+m>=ne)
		{
			m=now+m-ne;
			a[op].vis=1;
			sum=sum-(100-a[op].c)*a[op].w;
			s[op]=1;
			continue;
		}
		ne=ne-now-m;
		while(!q.empty()) q.pop();
		now=0;
		for(int j=1;j<op;j++)
		{
			if(a[j].vis) continue;
			q.push(make_pair(a[j].id,j));
			now+=(100-a[j].c);
		}
		if(now<ne) continue;
		now=0;
		while(!q.empty())
		{
			int u=q.top().second;
			q.pop();
			a[u].vis=1;
			if(now+100-a[u].c>=ne){a[u].le=now+100-a[u].c-ne;break;}
		}
		s[op]=1;
		sum=sum-(100-a[op].c)*a[op].w;
		a[op].vis=1;
	}
	printf("%d\n",sum);
	for(int i=1;i<=n;i++)
	{
		if(!s[i]) printf("%d 0\n",ans[i]+1);
		else printf("%d %d\n",ans[i],a[i].c);
	}
	return 0;
}
2020/10/21 16:11
加载中...