zoukankan      html  css  js  c++  java
  • 动态规划dp——天平2

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5616

    Jam's balance

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 2359    Accepted Submission(s): 964


    Problem Description
    Jim has a balance and N weights. (1N20)
    The balance can only tell whether things on different side are the same weight.
    Weights can be put on left side or right side arbitrarily.
    Please tell whether the balance can measure an object of weight M.
     
    Input
    The first line is a integer T(1T5) , means T test cases.
    For each test case :
    The first line is N , means the number of weights.
    The second line are N number, i'th number wi(1wi100) means the i'th weight's weight is wi .
    The third line is a number M . M is the weight of the object being measured.
     
    Output
    You should output the "YES"or"NO".
     
    Sample Input
    1 2 1 4 3 2 4 5
     
    Sample Output
    NO YES YES
    Hint
    For the Case 1:Put the 4 weight alone For the Case 2:Put the 4 weight and 1 weight on both side
     
     
     
    题解: 又是一道天平问题,本题类似于;排列组合,可以用母函数做!
      ok!
      首先我们定义一个数组 dp[ i ][ j]:表示用前i个砝码中的部分或全部,是否可以使得天平右边比左边重j克,或者左边比右边重 j 克;
              dp[i][j]==1 表示存在一种挂法 用前i个砝码挂在天平的  使得天平右边比左边重j克(或左边比右边重 j 克)
              dp[i][j]==0 表示不存在。
      其次 weight[ i ]:表示第i个砝码的重量。
          ( emmm,动态规划总是这样,dp数组的值一般对应问题的解,要想明白下标的含义及其关系)
      分析啦::
                        如果 不使用的i个砝码:则 d[i ][ j ] = d[i-1 ][ j ];
           如果 使用第i个砝码:    则 d[ i ][ j ]=max{  d[i-1][   (int) abs(  j- weight[i] )  ] , d[i-1][  j+weight[i]  ]      }
                    因为d[i][j] :如果使用第i个砝码,那么要使得天平右边比左边重j克( 或左边比右边重 j 克 ), 只有用前 i-1 个砝码,使得天平左偏  j + weight[i] 克,这时天
                    平右边边放第i个砝码,即天平左偏j 克,d[ i ][ j ] = d[i-1][  j+weight[i]  ]   ,其他情况同理。
     
    代码实现:
    #include<iostream>
    #include<cstring> 
    #include<cmath>
    using namespace std;
    int dp[25][2500];
    int main(){
    	int t;
    	cin>>t;
    	while(t--){
    		int n;
    		cin>>n;
    		memset(dp,0,sizeof(dp));
    		int a;
    		cin>>a;
    		dp[1][a]=dp[1][0]=1;
    		
    		for(int i=2;i<=n;i++){
    			cin>>a;
    			dp[i][0]=1;
    			for(int j=0;j<=2100;j++){
    				dp[i][j]=dp[i-1][j];
    				if(!dp[i][j]) {
    					dp[i][j]=max(dp[i-1][(int)abs(j-a) ],dp[i-1][j+a]);
    				}
    			}
    		}
    		int x;
    		cin>>x;
    		while(x--){
    			cin>>a;
    			if(dp[n][a])
    				cout<<"YES"<<endl;
    			else
    				cout<<"NO"<<endl;
    		}
    	
    	}
    }
    

      

  • 相关阅读:
    Hibernate逆向工程
    使用Hibernate连接Oracle 无法识别生成的SQL问题
    法线的变换矩阵
    搭建Struts2开发环境
    留存: struts2+jquery+json集成
    一些WebGL的资源
    9个WebGL的演示
    WPF动画制作简单的按钮动画
    C# /windowForm/WPF/SilverLight里面操作Word帮助类提供给大家
    高斯投影正反算的代码
  • 原文地址:https://www.cnblogs.com/z-bear/p/9473484.html
Copyright © 2011-2022 走看看