ZOJ 3703 Happy Programming Contest

2024-05-29 18:38

本文主要是介绍ZOJ 3703 Happy Programming Contest,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接~~>

做题感悟:这题比赛时想了好久才做出来,赛后一想其实就是 01 背包一下,记录各个体积的最优值就可以了,比赛时想多了。

解题思路:

               我直接开的二维数组 dp[ i ] [ j ]  代表达到体积 i ,做了 j 道题所达到的最优状态 : dp[ i ] [ j ]  = { dp [ i - v ] [ j - 1 ] } 的最优值 ,其实就是二维的背包 。

代码:

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std ;
#define INT long long int
const int INF = 0x3f3f3f3f ;
const int MX = 1000 + 10 ;
int C ,n ;
int dp[2][MX][55] ;
struct node
{int v ,w ;
}T[MX] ;
bool cmp(node a, node b)
{if(a.v == b.v)  return a.w > b.w ;elsereturn a.v < b.v ;
}
void input()
{scanf("%d%d" ,&C ,&n) ;for(int i = 0 ;i < n ; ++i)scanf("%d" ,&T[i].v) ;for(int i = 0 ;i < n ; ++i)scanf("%d" ,&T[i].w) ;
}
int main()
{//freopen("input.txt" ,"r" ,stdin) ;int Tx ;scanf("%d" ,&Tx) ;while(Tx--){input() ;int ans = 0 ,num = 0 ,Wx = INF ;sort(T ,T+n ,cmp) ;memset(dp[0] ,-1  ,sizeof(dp[0])) ;memset(dp[1] ,0 ,sizeof(dp[1])) ;dp[0][0][0] = 0 ;for(int t = 1 ;t <= n ; ++t)for(int j = C  ;j >= T[t-1].v ; --j)for(int i = t ;i >= 1 ; --i)if(dp[0][j-T[t-1].v][i-1] != -1){int v = T[t-1].v ;int w = T[t-1].w ;if(dp[0][j][i] < dp[0][j-v][i-1] + w){dp[0][j][i] = dp[0][j-v][i-1] + w ;dp[1][j][i] = dp[1][j-v][i-1] + j ;}else if(dp[0][j][i] == dp[0][j-v][i-1] + w && dp[1][j][i] > dp[1][j-v][i-1] + j){dp[0][j][i] = dp[0][j-v][i-1] + w ;dp[1][j][i] = dp[1][j-v][i-1] + j ;}if(dp[0][j][i] > ans || (dp[0][j][i] == ans && i > num) || (dp[0][j][i] == ans && i == num && Wx > dp[1][j][i])){ans = dp[0][j][i] ;num = i ;Wx = dp[1][j][i] ;}}if(Wx != INF)cout<<ans<<" "<<num<<" "<<Wx<<endl ;else    cout<<"0 0 0"<<endl ;}return 0 ;
}



这篇关于ZOJ 3703 Happy Programming Contest的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1014327

相关文章

数论ZOJ 2562

题意:给定一个数N,求小于等于N的所有数当中,约数最多的一个数,如果存在多个这样的数,输出其中最大的一个。 分析:反素数定义:对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数。 性质一:一个反素数的质因子必然是从2开始连续的质数。 性质二:p=2^t1*3^t2*5^t3*7

zoj 1721 判断2条线段(完全)相交

给出起点,终点,与一些障碍线段。 求起点到终点的最短路。 枚举2点的距离,然后最短路。 2点可达条件:没有线段与这2点所构成的线段(完全)相交。 const double eps = 1e-8 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;

zoj 4624

题目分析:有两排灯,每排n个,每个灯亮的概率为p,每个灯之间互不影响,亮了的灯不再灭,问两排中,每排有大于等于m个灯亮的概率。 设dp[ i ][ j ]为第一排亮了i个灯,第二排亮了j个灯,距离目标状态的期望天数。显然 i >= m ,j >= m时 , dp[ i ][ j ] = 0 。 状态转移 : 第一排亮了a个灯,a 在[ 0 , n - i] 之间,第二排亮了b个灯 , b 在

zoj 3228 ac自动机

给出一个字符串和若干个单词,问这些单词在字符串里面出现了多少次。单词前面为0表示这个单词可重叠出现,1为不可重叠出现。 Sample Input ab 2 0 ab 1 ab abababac 2 0 aba 1 aba abcdefghijklmnopqrstuvwxyz 3 0 abc 1 def 1 jmn Sample Output Case 1 1 1 Case 2

ZOJ Monthly, August 2014小记

最近太忙太忙,只能抽时间写几道简单题。不过我倒是明白要想水平提高不看题解是最好的了。 A  我只能死找规律了,无法证明 int a[50002][2] ;vector< vector<int> > gmax , gmin ;int main(){int n , i , j , k , cmax , cmin ;while(cin>>n){/* g

2014 Multi-University Training Contest 8小记

1002 计算几何 最大的速度才可能拥有无限的面积。 最大的速度的点 求凸包, 凸包上的点( 注意不是端点 ) 才拥有无限的面积 注意 :  凸包上如果有重点则不满足。 另外最大的速度为0也不行的。 int cmp(double x){if(fabs(x) < 1e-8) return 0 ;if(x > 0) return 1 ;return -1 ;}struct poin

2014 Multi-University Training Contest 7小记

1003   数学 , 先暴力再解方程。 在b进制下是个2 , 3 位数的 大概是10000进制以上 。这部分解方程 2-10000 直接暴力 typedef long long LL ;LL n ;int ok(int b){LL m = n ;int c ;while(m){c = m % b ;if(c == 3 || c == 4 || c == 5 ||

2014 Multi-University Training Contest 6小记

1003  贪心 对于111...10....000 这样的序列,  a 为1的个数,b为0的个数,易得当 x= a / (a + b) 时 f最小。 讲串分成若干段  1..10..0   ,  1..10..0 ,  要满足x非递减 。  对于 xi > xi+1  这样的合并 即可。 const int maxn = 100008 ;struct Node{int

AtCoder Beginner Contest 370 Solution

A void solve() {int a, b;qr(a, b);if(a + b != 1) cout << "Invalid\n";else Yes(a);} B 模拟 void solve() {qr(n);int x = 1;FOR(i, n) FOR(j, i) qr(a[i][j]);FOR(i, n) x = x >= i ? a[x][i]: a[i][x];pr2(

ZOJ 3324 Machine(线段树区间合并)

这道题网上很多代码是错误的,由于后台数据水,他们可以AC。 比如这组数据 10 3 p 0 9 r 0 5 r 6 9 输出应该是 0 1 1 所以有的人直接记录该区间是否被覆盖过的方法是错误的 正确方法应该是记录这段区间的最小高度(就是最接近初始位置的高度),和最小高度对应的最长左区间和右区间 开一个sum记录这段区间最小高度的块数,min_v 记录该区间最小高度 cover