18: Array C
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 586 Solved: 104
[Submit][Status][Web Board]
Description
Giving two integers and and two arrays and both with length , you should construct an array also with length which satisfied:
1.0≤Ci≤Ai(1≤i≤n)
2.
and make the value S be minimum. The value S is defined as:
Input
There are multiple test cases. In each test case, the first line contains two integers n(1≤n≤1000) andm(1≤m≤100000). Then two lines followed, each line contains n integers separated by spaces, indicating the array Aand B in order. You can assume that 1≤Ai≤100 and 1≤Bi≤10000 for each i from 1 to n, and there must be at least one solution for array C. The input will end by EOF.
Output
For each test case, output the minimum value S as the answer in one line.
Sample Input
3 4 2 3 4 1 1 1
Sample Output
6
HINT
In the sample, you can construct an array [1,1,2](of course [1,2,1] and [2,1,1] are also correct), and is 6.
题目大意:给你n,m。表示a数组和b数组。然后让你选m个数组成c数组,保证c[i] <= a[i],要求sigma(c[i]*c[i]*b[i])求和最小。可能没描述不太清楚,自己再看看题吧。。。
解题思路:自己想了一个mlogn的做法,但是一直超时到死。。。赛后听大牛的解法,的确很巧妙ORZ。
自己的超时想法:
#include<stdio.h> #include<algorithm> //#include<string.h> //#include<math.h> //#include<string> //#include<iostream> #include<queue> //#include<stack> //#include<map> //#include<vector> //#include<set> using namespace std; typedef long long LL; #define mid (L+R)/2 #define lson rt*2,L,mid #define rson rt*2+1,mid+1,R const int maxn = 1e3 + 30; const LL INF = 0x3f3f3f3f; const LL mod = 9973; typedef long long LL; typedef unsigned long long ULL; struct Num{ int b, c, prod, id; bool operator < (const Num & rhs)const{ return prod > rhs.prod; } }nums[maxn]; int A[maxn], B[maxn], ans[maxn]; priority_queue<Num>PQ; int Scan() { //输入外挂 int res = 0, flag = 0; char ch; if((ch = getchar()) == ‘-‘) flag = 1; else if(ch >= ‘0‘ && ch <= ‘9‘) res = ch - ‘0‘; while((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) res = res * 10 + (ch - ‘0‘); return flag ? -res : res; } void Out(int a) { //输出外挂 if(a < 0) { putchar(‘-‘); a = -a; } if(a >= 10) Out(a / 10); putchar(a % 10 + ‘0‘); } int main(){ int n,m; while(scanf("%d %d",&n,&m)!=EOF){ while(!PQ.empty()) PQ.pop(); for(int i = 1; i <= n; ++i){ scanf("%d",&A[i]); // A[i] = Scan(); nums[i].c = 1; } for(int i = 1; i <= n; i++){ scanf("%d",&nums[i].b); // nums[i].b = Scan(); nums[i].id = i; nums[i].prod = nums[i].b * (nums[i].c*nums[i].c); PQ.push(nums[i]); } Num nm = PQ.top(); PQ.pop(); ans[nm.id]++; Num tmp; for(int i = 1; i < m; ++i){ if(PQ.empty()){ ans[nm.id] += m-i; break; } // cout<<PQ.size()<<" ++++"<<endl; tmp = PQ.top(); // printf("%d %d %d++\n",tmp.id,tmp.c,tmp.prod); nm.c++; nm.prod = nm.b*nm.c*nm.c; if(nm.c > A[nm.id]){ PQ.pop(); nm = tmp; ans[nm.id] = nm.c; continue; } if(tmp.prod < nm.prod){ PQ.pop(); PQ.push(nm); nm = tmp; ans[nm.id] = nm.c; }else{ ans[nm.id] = nm.c; } } int res = 0; for(int i = 1; i <= n; ++i){ // printf("%d\n",ans[i]); res += nums[i].b * ans[i] * ans[i]; ans[i] = 0; } //printf("%d\n",res); Out(res); puts(""); } return 0; }
大牛的解法:
#include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<string> #include<iostream> #include<queue> #include<stack> #include<map> #include<vector> #include<set> using namespace std; typedef long long LL; #define mid (L+R)/2 #define lson rt*2,L,mid #define rson rt*2+1,mid+1,R const int maxn = 1e6 + 30; const LL INF = 0x3f3f3f3f; const LL mod = 9973; typedef long long LL; typedef unsigned long long ULL; int a[maxn],b[maxn] ,cost[maxn]; int main(){ int n, m; while(scanf("%d%d",&n,&m)!=EOF){ for(int i = 1; i <= n; ++i){ scanf("%d",&a[i]); } for(int i = 1; i <= n; ++i){ scanf("%d",&b[i]); } int cnt = 0; for(int i = 1; i <= n; ++i){ for(int j = 1; j <= a[i]; ++j){ cost[cnt] = (2*j-1)*b[i]; cnt++; } } sort(cost,cost+cnt); LL res = 0; for(int i = 0; i < m; ++i){ res += cost[i]; } printf("%lld\n",res); } return 0; }