hdu 6092 Rikka with Subset 背包(贪心)

Rikka with Subset

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Yuta has  n  positive  A1An  and their sum is  m . Then for each subset  S  of  A , Yuta calculates the sum of  S

Now, Yuta has got  2n  numbers between  [0,m] . For each  i[0,m] , he counts the number of  i s he got as  Bi .

Yuta shows Rikka the array  Bi  and he wants Rikka to restore  A1An .

It is too difficult for Rikka. Can you help her?  
 

Input
The first line contains a number  t(1t70) , the number of the testcases. 

For each testcase, the first line contains two numbers  n,m(1n50,1m104) .

The second line contains  m+1  numbers  B0Bm(0Bi2n) .
 

Output
For each testcase, print a single line with  n  numbers  A1An .

It is guaranteed that there exists at least one solution. And if there are different solutions, print the lexicographic minimum one.
 

Sample Input
  
  
2 2 3 1 1 1 1 3 3 1 3 3 1
 

Sample Output
  
  
1 2 1 1 1
Hint
In the first sample, $A$ is $[1,2]$. $A$ has four subsets $[],[1],[2],[1,2]$ and the sums of each subset are $0,1,2,3$. So $B=[1,1,1,1]$

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.StringTokenizer;


public class Main {
    
    public static void main(String[] args) {
        new Task().solve();
    }
}



class Task {
    InputReader in = new InputReader(System.in) ;
    PrintWriter out = new PrintWriter(System.out) ;
    
    void solve(){
        int t = in.nextInt() ;
        while(t-- > 0){
            int n = in.nextInt() ;
            int m = in.nextInt() ;
            long[] B = new long[m+1] ;
            int sum = 0 ; 
            for(int i = 0 ; i <= m ; i++){
                B[i] = in.nextLong() ;
            }
            long[] dp = new long[m+1] ;
            Arrays.fill(dp, 0) ;
            dp[0] = 1 ;
            boolean fisrt = true ;
            int d = 0 ;
            for(int i = 1 ; i <= m ; i++){
                long cnt = B[i] - dp[i] ;
                if(cnt <= 0){
                    continue ;
                }
                for(int k = 0 ; k < cnt ; k++){
                    out.print(fisrt ? "" : " ") ;
                    out.print(i) ;
                    fisrt = false ;
                    for(int j = m ; j >= i ; j--){
                        dp[j] += dp[j-i] ;
                    }
                }
            }
            out.println() ;
        }  
        out.flush() ;
    }
}

class InputReader {    
    public BufferedReader reader;    
    public StringTokenizer tokenizer;    
    
    public InputReader(InputStream stream) {    
        reader = new BufferedReader(new InputStreamReader(stream), 32768);    
        tokenizer = new StringTokenizer("");    
    }    
    private void eat(String s) {    
        tokenizer = new StringTokenizer(s);    
    }    
    
    public String nextLine() {     
        try {    
            return reader.readLine();    
        } catch (Exception e) {    
            return null;    
        }    
    }    
    
    public boolean hasNext() {    
        while (!tokenizer.hasMoreTokens()) {    
            String s = nextLine();    
            if (s == null)    
                return false;    
            eat(s);    
        }    
        return true;    
    }    
    
    public String next() {    
        hasNext();    
        return tokenizer.nextToken();    
    }    
    
    public int nextInt() {    
        return Integer.parseInt(next());    
    }    
    
    public int[] nextInts(int n) {    
        int[] nums = new int[n];    
        for (int i = 0; i < n; i++) {    
            nums[i] = nextInt();    
        }    
        return nums;    
    }    
    
    public long nextLong() {    
        return Long.parseLong(next());    
    }    
    
    public double nextDouble() {    
        return Double.parseDouble(next());    
    }    
    
    public BigInteger nextBigInteger() {    
        return new BigInteger(next());    
    }    
    
}    

卡的好严,多了减法就TLE

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.StringTokenizer;


public class Main {
    
    public static void main(String[] args) {
        new Task().solve();
    }
}



class Task {
    InputReader in = new InputReader(System.in) ;
    PrintWriter out = new PrintWriter(System.out) ;
    
    void solve(){
        int t = in.nextInt() ;
        while(t-- > 0){
            int n = in.nextInt() ;
            int m = in.nextInt() ;
            long[] B = new long[m+1] ;
            int sum = 0 ; 
            for(int i = 0 ; i <= m ; i++){
                B[i] = in.nextLong() ;
            }
            long[] dp = new long[m+1] ;
            Arrays.fill(dp, 0) ;
            dp[0] = 1 ;
            boolean fisrt = true ;
            int d = 0 ;
            for(int i = 1 ; i <= m ; i++){
                long cnt = B[i] ;
                if(cnt <= 0){
                    continue ;
                }
                for(int k = 0 ; k < cnt ; k++){
                    out.print(fisrt ? "" : " ") ;
                    out.print(i) ;
                    fisrt = false ;
                    for(int j = m ; j >= i ; j--){
                        dp[j] += dp[j-i] ;
                        B[j] -= dp[j] ;
                    }
                }
            }
            out.println() ;
        }  
        out.flush() ;
    }
}

class InputReader {    
    public BufferedReader reader;    
    public StringTokenizer tokenizer;    
    
    public InputReader(InputStream stream) {    
        reader = new BufferedReader(new InputStreamReader(stream), 32768);    
        tokenizer = new StringTokenizer("");    
    }    
    private void eat(String s) {    
        tokenizer = new StringTokenizer(s);    
    }    
    
    public String nextLine() {     
        try {    
            return reader.readLine();    
        } catch (Exception e) {    
            return null;    
        }    
    }    
    
    public boolean hasNext() {    
        while (!tokenizer.hasMoreTokens()) {    
            String s = nextLine();    
            if (s == null)    
                return false;    
            eat(s);    
        }    
        return true;    
    }    
    
    public String next() {    
        hasNext();    
        return tokenizer.nextToken();    
    }    
    
    public int nextInt() {    
        return Integer.parseInt(next());    
    }    
    
    public int[] nextInts(int n) {    
        int[] nums = new int[n];    
        for (int i = 0; i < n; i++) {    
            nums[i] = nextInt();    
        }    
        return nums;    
    }    
    
    public long nextLong() {    
        return Long.parseLong(next());    
    }    
    
    public double nextDouble() {    
        return Double.parseDouble(next());    
    }    
    
    public BigInteger nextBigInteger() {    
        return new BigInteger(next());    
    }    
    
}    





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值