zoukankan      html  css  js  c++  java
  • [洛谷P2113] 看球泡妹子

    洛谷题目链接:看球泡妹子

    题目背景

    2014年巴西世界杯开幕了,现在满城皆是世界杯,商家们利用它大赚一笔,小明和小红也借此机会增进感情。

    题目描述

    本届世界杯共有N支球队,M场比赛。男球迷小明喜欢看比赛,女球迷小红喜欢看帅哥。每支球队在小明眼里的实力值为Ai,在小红眼里的帅哥数量为Bi。

    每场比赛有两个球队对抗,它们的编号分别是Pi和Qi。小明认为一场比赛的精彩度等于两队实力的乘积,小红则认为是两队帅哥数量之和。

    由于体力的限制,他们最多只能看K场比赛。当然,只要看比赛,两个人一定会一起看。小明作为男生,理应迁就一下女生,所以,请你写一个程序,求出小红看到比赛的精彩度总和不小于C的情况下,小明看到比赛的精彩度的最大总和。

    输入输出格式

    输入格式:

    第1行,4个正整数N,M,K,C。

    第2行,N个空格隔开的正整数Ai。

    第3行,N个空格隔开的正整数Bi。

    之后M行,每行两个正整数Pi,Qi。

    输出格式:

    一行,一个正整数表示小明看到比赛的精彩度的最大总和。如果无论如何都无法满足小红的要求,输出-1.

    输入输出样例

    输入样例#1:

    4 3 2 5
    2 2 1 3
    1 1 1 2
    1 2
    2 3
    3 4

    输出样例#1:

    7

    说明

    对于20%数据,N,M,K<=5。

    对于全部数据,N<=100,K<=M<=100,Ai,Bi<=10,C<=1000.

    一句话题意: n个队伍间有比赛, A,B两个参数描述队伍,有m场比赛,看一场(x)(y)的比赛小明可以获得(A_x*A_y)的精彩度,小红可以获得(B_x+B_y)的精彩度. 问看k场的情况下,要使小红得到的精彩度大于c,小明可以得到的最大精彩度是多少.

    题解: 因为(B_x+B_y)并不大,最多也只有2000,所以可以考虑用DP将小红得到的精彩度作为背包的费用存下来,那么选k场也就可以看成是一个01背包.那么可以定义状态(f[i][j][k])表示选到了第(j)场比赛,看了(i)场,小红得到的精彩度为(k). 可以得到状态转移方程:

    [f[i][j][k] = max(f[i-1][j-1][k-v]+w, f[i][j][k]) ]

    其中k为枚举的精彩度,v为看这次比赛小红可以得到的精彩度,w为小明可以得到的精彩度.

    然后注意一下赋初始值的问题就可以了.

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace std;
    const int N=100+5;
    
    int n, m, k, c, ans = -1;
    int f[N][N][2000+5];
    //in the front i_th games
    //watched j games
    //the level of the game is l
    
    struct team{
        int a, b;
    }t[N];
    
    struct game{
        int x, y, v, w;
    }g[N];
    
    int main(){
        //freopen("data.in","r",stdin);
        cin >> n >> m >> k >> c;
        memset(f,128,sizeof(f)); f[0][0][0] = 0;
        for(int i=1;i<=m;i++) f[i][0][0] = 0;
        for(int i=1;i<=n;i++) cin >> t[i].a;
        for(int i=1;i<=n;i++) cin >> t[i].b;
        for(int i=1;i<=m;i++){
    	    cin >> g[i].x >> g[i].y;
    	    g[i].w = t[g[i].x].a*t[g[i].y].a;
    	    g[i].v = t[g[i].x].b+t[g[i].y].b;
        }
        for(int i=1;i<=k;i++)//the chances to see the game
        for(int j=i;j<=m;j++)//game
            for(int l=2000;l>=0;l--){//the level of the game
            f[j][i][l] = max(f[j][i][l], f[j-1][i][l]);
            if(l >= g[j].v) f[j][i][l] = max(f[j][i][l], f[j-1][i-1][l-g[j].v]+g[j].w);
            if(l >= c) ans = max(ans, f[j][i][l]);
    	}
        printf("%d
    ",ans);
        return 0;
    }
    

    状态定义的比较奇葩不要见怪哈..

  • 相关阅读:
    练习与突破
    HTML input type=file文件选择表单的汇总(一)
    webpack学习之—— Configuration(配置)
    webpack学习之—— Plugins
    webpack学习之—— Loaders
    webpack学习之——Output
    webpack学习之——Entry Points(入口起点)
    CSS3 3D transform变换
    get和post请求的区别
    日期格式之——剩余时间(天,小时,分,秒)的计算方法
  • 原文地址:https://www.cnblogs.com/BCOI/p/9028534.html
Copyright © 2011-2022 走看看