山东省第八届acm省赛 company

company

Time Limit: 1000MS  Memory Limit: 65536KB
Problem Description

There are n kinds of goods in the company, with each of them has a inventory of  and direct unit benefit . Now you find due to price changes, for any goods sold on day i, if its direct benefit is val, the total benefit would be ival.
Beginning from the first day, you can and must sell only one good per day until you can't or don't want to do so. If you are allowed to leave some goods unsold, what's the max total benefit you can get in the end?

Input

The first line contains an integers n(1≤n≤1000).
The second line contains n integers val1,val2,..,valn(−100≤.≤100).
The third line contains n integers cnt1,cnt2,..,cntn(1≤≤100).

Output

Output an integer in a single line, indicating the max total benefit.

Example Input
4
-1 -100 5 6
1 1 1 2
Example Output
51
Hint

sell goods whose price with order as -1, 5, 6, 6, the total benefit would be -1*1 + 5*2 + 6*3 + 6*4 = 51.

Author
“浪潮杯”山东省第八届ACM大学生程序设计竞赛(感谢青岛科技大学)
当初比赛做这道题的时候时间已经所剩无几  榜单上看到这道题大多数的队伍都做出来了 所以我们觉得这道题应该不是特别难 直接用暴力排序所有的单价大小来写 把所有的单价和数量都拆分 然后从小到大排列出来 一件物品可以选择卖或者不卖 如果物品不卖的话肯定是先不卖单价最小(负数时 正数就不需要不买了 因为无论怎么如何从小不卖都是总收入减小)的  这样的所有的商品卖的天数都会减少一天 通过循环可以找出价值最大的那一天 但是因为比赛时的时间原因 没能写出这个程序
不提的时候觉得这道题的时间复杂度太高了 百度到了另一种办法 前面基本差不多 就是后面的时候 不再是以此不售卖单价最小的商品 而是用一个中间和来动态的变化天数 并且用来判断意见物品是否售卖 
ac代码:
[cpp]  view plain  copy
  1. #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    using namespace std;


    int val[1005], cnt;
    int v[100050];


    int main()
    {
        int n;
        while(~scanf("%d", &n))
        {
           memset(v, 0, sizeof(v));
           memset(val, 0, sizeof(val));
            long long t = 1;//统计的时候天数
            for(int i = 1; i <= n; i++)
                scanf("%d", &val[i]);//输入商品的单价
            for(int i = 1; i <= n; i++)
                {
                    scanf("%d", &cnt);
                    for(int j = t ; j < t + cnt; j ++)
                        v[j] = val[i];  //所有对应时间段内赋予当前单价的值 v数组即是按照单价和数量展开后的总得数组
                    t += cnt;//时间求和
                }
            t --;//减去最开始的1
            sort(v+1, v + t+1);//v数组进行升序排序
            long long  ans = 0;
            long long sum = 0;//求和的数值定义为long long类型防止爆数
            for(int i = t; i >= 1; i--)
            {
                if( v[i] + sum < 0)//跳过会使总价值变小的物品
                    continue;
                else
                {
                    ans += v[i] + sum;//通过这里对sum的运用 从而使天数乘以价值能够做都做到动态化的过程 而不再是单价乘以天数
                    sum += v[i];//sum也用于比较筛选会使总价值变小的物品
                }
            }
            cout << ans <<endl;
        }
        return 0;
    }
      

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值