Gym 101128C想法题

来源:互联网 发布:seo大牛张辉的网站 编辑:程序博客网 时间:2024/06/07 01:24

题目里有个图抠不下来,就不放原题了。

【题意】

需要你给n块布染色,要求最后每块布颜色都不同。

每一次可以选择颜色为C的布中(C已经存在)的前F块布,将之染成一种新颜色,并且剩下的颜色为C的布染成另外一种新颜色。

每块布有个ai,表示染一次色消耗的墨水数量。

问总共最小墨水数量是多少。

【解法】

找了很久的规律发现。。倒着做就好了。

相当于将n块颜色不同的布染成颜色相同的。

假设当前有n块布,你要选择两块染成相同颜色,是不是选消耗墨水数量最少的两块?(没毛病)

每次都选消耗最小的两块染成同一颜色,把消耗加起来就是了。


用优先队列,取前两个,记录消耗和,再把两个加起来放回优先队列,直到最后只剩一块布。

写的时候以为还要记录颜色,傻乎乎开了个结构体,起始并不用。。

懒得改了直接放上来吧。

#include<cstdio>#include<queue>using namespace std;struct node{__int64 w,color;//注意此处消耗要用__int64,一个大坑friend bool operator <(node a,node b){return a.w>b.w;}}e,e1,e2;priority_queue<node>q; int main(){int t;__int64 ans=0;scanf("%d",&t);int n;while(t--){ans=0;int cnt=0;while(!q.empty())q.pop();scanf("%d",&n);for(int i=0;i<n;i++){scanf("%I64d",&e.w);e.color=cnt++;q.push(e);}while(1){e1=q.top();q.pop();if(!q.empty()){e2=q.top();q.pop();ans+=e1.w;ans+=e2.w;}else break;   e1.w+=e2.w; e1.color=cnt++; q.push(e1);}printf("%I64d\n",ans);}return 0;}


原创粉丝点击