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;
    		}
    	
    	}
    }
    

      

  • 相关阅读:
    递归函数的原理
    html布局-子div浮动后,父容器撑不开解决
    权限设计——控制显示字段——设计思考
    winform上传文件到服务器——资料整理
    windows server自动化发布——技术积累与整理
    Docker——概念学习
    javascript中的var,let,const关键字
    Web前端面试图
    上传与预览图片
    每个程序员都应该知道延迟数—Latency Numbers Every Programmer Should Know
  • 原文地址:https://www.cnblogs.com/z-bear/p/9473484.html
Copyright © 2011-2022 走看看