哈理工 网络赛

大神博客 :http://m.blog.csdn.net/just_sort/article/details/78775866

题目描述

在acimo星球, tabris 是一名勇敢的屠龙勇士,在上绿岛屠龙前决定挑选N种装备武装自己,现在每种装备有两个,**但每种装备tabris必须选择拿一个**,**不能多也不能少**。
每件装备有自己的属性值,能给tabris属性加成。
对于不同种类的装备之间有叠加效果,如果选择多件装备,最终的属性加成为他们的乘积。
若tabris初始属性值为0,最后属性加成的期望是多少。

输入描述:

有多组测试样例,输入到文件结束。
每组测试数据的第一行包含一个正整数NN,表示装备的种类数。
接下来N行,每行两个正整数ai、bi,表示两个不同的第ii种装备的属性加成值。

N∈[1,103]
ai,bi∈[1,106]

输出描述:

对于每组测试数据输出一个整数,为了方便输出最终的结果先乘2
N
再对1e9+7取模后的值。
示例1

输入

4
1 2
3 4
5 6
7 8

输出

3465

说明

3465 = (1*3*5*7) + (1*3*5*8) +(1*3*6*7) + (1*3*6*8) + (1*4*5*7) + (1*4*5*8) + (1*4*6*7) + (1*4*6*8) + (2*3*5*7) + (2*3*5*8) + (2*3*6*7) + (2*3*6*8) + (2*4*5*7) + (2*4*5*8) + (2*4*6*7) + (2*4*6*8) ;


题意 : 每组数据选择一个,将每组数据中选出的数据相乘,求最后的和。
思路 : 先考虑只有一组数据的情况,答案即为两个数相加的和,在考虑有两组数据的情况,在纸上写一下会发现规律,所有数据的和即为每组数据的和相乘

代码示例 :
int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int n;
    int a, b;
    
    while(~scanf("%d", &n)){
        ll ans = 1;
        for(int i = 1; i <= n; i++){
            scanf("%d%d", &a, &b);
            ans *= 1ll*(a+b)%mod;
            ans %= mod;
        }
        printf("%lld
", ans%mod);
    }
    

    return 0;
}

c .

题目描述

小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时间和固定的伤害值为:

1.乌鸦坐飞机 释放时间:x 固定伤害值:a

2.蜘蛛吃耳屎 释放时间:y 固定伤害值:b

3.饿狼前进  释放时间:z 固定伤害值:c


他还有一个大招,其释放的时间是一个区间【L,R】,可以在区间内任意时间点释放出技能,其如果在L+i时刻释放技能,其能够打出的伤害值为:temp+A*i

这里temp值表示技能的基础伤害(同时也就是在时刻L释放技能的伤害值),A是一个常数。


小明很喜欢研究连招使得在有限的时间内打出最高的伤害,现在他想要在T长度单位时间内打出最高的伤害,问这个最大伤害值。

输入描述:

本题包含多组数据。
输入格式为:
T
x a
y b
z c
L R temp A
数据范围:
1<=T<=1e5
1<=x,y,z,L,R<=T
L<=R
<=a,b,c,temp,A<=1e5

输出描述:

输出包含一行,输出能够打出的最高伤害值。
示例1

输入

8
3 1
2 3
1 3
3 3 3 3

输出

24

备注:

大招:蓄力时间最短L秒,最多R秒。无限次释放,释放之后照成的伤害是随着时间增加的
蓄力L秒释放能够造成Temp的伤害
蓄力L+1秒释放能够造成Temp+1*A的伤害
依次类推


题目分析 : 如果没有大招,那这题就是一个简单的线性dp,扫一遍就过了,但是现在有大招,加了一位博友,第一次才知道,原来这种公式是可以推出来的,dp[i] = max(dp[i], dp[j]+temp+A*(i-l-j)),i-r <= j <= i-l ,维护当时间是 i 时,寻找此时的最大值并且继续更新。
  但是你单纯按照着这个递推公式推,你会出错了,因为你只是确保是dp[]的最大,但是时间是不确定的,因为有可能同一个dp值,但是有两个时间都是等于这个,因此可以将公式进一步变形,dp[i] = max(dp[i], dp[j]-A*j + temp + A*(i-l)),这里可以用优先队列去维护,但是有
  个点一定要知道,就是 你的时间是递推的,因此在区间内不符合范围的解,此不符合的区间的前端以后也是不会用到的,因此可以之间删除,但是后面的点以后可能会用到,要保存下来。

代码示例 :
const int eps = 1e5+5;
const double pi = acos(-1.0);
const int inf = 1<<29;
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define ll long long

ll dp[eps];

struct node
{
    ll w;
    int u;
    
    bool operator< (const node &c)const{
        return w < c.w;
    }
    node(ll _w, int _u):w(_w), u(_u){}
};

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int t;
    
    int x, a, y, b, z, c;
    int l, r, tem, A;
    priority_queue<node>que;
    stack<node>s;
    //node v(0, 0);
    
    while(~scanf("%d", &t)){
        scanf("%d%d", &x, &a);
        scanf("%d%d", &y, &b);
        scanf("%d%d", &z, &c);
        scanf("%d%d%d%d", &l, &r, &tem, &A);
        
        while(!que.empty()) que.pop();
        while(!s.empty()) s.pop();
        memset(dp, 0, sizeof(dp));
        
        ll ans = 0;
        for(int i = 1; i <= t; i++){
            if (i >= x) dp[i] = max(dp[i], dp[i-x]+a);
            if (i >= y) dp[i] = max(dp[i], dp[i-y]+b);
            if (i >= z) dp[i] = max(dp[i], dp[i-z]+c);
             
            que.push(node(0, 0));
            if (i >= l){
                while(!que.empty()){
                    node v = que.top();
                    if (v.u < i-r || v.u > i-l) que.pop();
                    else break;
                    if (v.u > i-l) s.push(v);
                }
                node v = que.top();
                dp[i] = max(dp[i], v.w+1ll*tem+1ll*A*(i-l));
                //if (i == 2) printf("@@%lld %d %d %d", v.w, tem, A, i-l);
            }
            que.push(node(dp[i]-1ll*A*i, i));
            while(!s.empty()) {
                que.push(s.top());
                s.pop();
            } 
            ans = max(ans, dp[i]);
            //printf("**%lld
", dp[i]);   
        }
        printf("%lld
", ans);
    }

    return 0;
}

另一种写法 : 要好好 理解一下为什么 ret 要初始化为 long long 的负无穷

const int eps = 1e5+5;
const double pi = acos(-1.0);
const int inf = 1<<29;
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define ll long long

ll dp[eps];
struct node
{
    int l, r, k;
    ll w;
}tree[eps<<2];
ll maxx;

void build(int l, int r, int k){
    tree[k].l = l, tree[k].r = r;
    if (l == r){
        tree[k].w = 0;
        return;
    }
    int m = (l + r)>>1;
    build(l, m, k<<1);
    build(m+1, r, k<<1|1);
    tree[k].w = max(tree[k<<1].w,tree[k<<1|1].w);
}

ll query(int L, int R, int k){
    if (L <= tree[k].l && tree[k].r <= R){
        return tree[k].w;
    }
    int m = (tree[k].l + tree[k].r) >> 1;
    ll ret = -__LONG_LONG_MAX__; // 初始化为long long 的负无穷
    if (L <= m) ret = max(ret, query(L, R, k<<1));
    if (R > m) ret = max(ret, query(L, R, k<<1|1));
    return ret;
}

void update(int pos, ll val, int k){
    if (tree[k].l == tree[k].r){
        tree[k].w = val;
        return;
    }
    int m = (tree[k].l + tree[k].r) >> 1;
    if (pos <= m) update(pos, val, k<<1);
    else update(pos, val, k<<1|1);
    tree[k].w = max(tree[k<<1].w,tree[k<<1|1].w);
}

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int t;
    int x, a, y, b, z, c;
    int l, r, tem, A;
    
    while(~scanf("%d", &t)){
        scanf("%d%d", &x, &a);
        scanf("%d%d", &y, &b);
        scanf("%d%d", &z, &c);
        scanf("%d%d%d%d", &l, &r, &tem, &A);
        
        memset(dp, 0, sizeof(dp));
        build(0, t, 1);
        ll ans = 0;
        for(int i = 1; i <= t; i++){
            if (i >= x) dp[i] = max(dp[i], dp[i-x]+a);
            if (i >= y) dp[i] = max(dp[i], dp[i-y]+b);
            if (i >= z) dp[i] = max(dp[i], dp[i-z]+c);
            if (i >= l) {
                int L = i - r, R = i - l;
                if (L < 0) L = 0; 
                dp[i] = max(dp[i], query(L, R, 1)+1ll*tem+1ll*A*(i-l));
            }
            update(i, dp[i]-1ll*A*i, 1);  
            ans = max(ans, dp[i]); 
        }
        printf("%lld
", ans);
    }
    return 0;
}
东北日出西边雨 道是无情却有情
原文地址:https://www.cnblogs.com/ccut-ry/p/8034657.html