动态规划问题练习

1.是否能通过考试

Description

小张想要通过明天的考试。他知道考题的分值分布,也知道考试中要拿到每一个题目需要耗费的时间。假设考试时长为h,共n个题目,需要拿到p分才能通过考试。现在已知每个考题的得分与耗时,请你判断小张能否通过合理安排时间,而通过考试,并给出通过考试的最短时间。

Input

输入第一行为测试用例个数.每一个用例有若干行,第一行为任务数量n、考试时常h、通过分数p,下面的n行是每一个题目的耗时和得分。所有数值用空格分开。

Output

对每一个用例输出一行,如果能够通过考试,则输出“YES”和消耗最短时间,用空格隔开。 否则,输出“NO”。

Sample Input 1 

1
5 40 21 
12 10 
16 10 
20 10 
24 10 
8 3 

Sample Output 1

YES 36

ANSWER:

import java.util.Scanner;
public class Main {

    public static int getResult (int n, int h, int p, int[] score, int[] time) {
        int[] dp = new int[h + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = h; j >= 1; j--) {
                if (j - time[i] >= 0)
                    dp[j] = Math.max(dp[j], dp[j - time[i]] + score[i]);
            }
        }
        //System.out.println(Arrays.toString(dp));
        for (int j = 1; j <= h; j++) {
            if (dp[j] >= p)
                return j;
        }
        return -1;
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int rounds = Integer.valueOf(scan.nextLine());
        for (int i = 0; i < rounds; i++) {
            String line = scan.nextLine();
            String[] arr = line.split(" ");
            int n = Integer.valueOf(arr[0]);
            int h = Integer.valueOf(arr[1]);
            int p = Integer.valueOf(arr[2]);
            int[] score = new int[n + 1];
            int[] time = new int[n + 1];
            for (int j = 1; j <= n; j++) {
                String problem = scan.nextLine();
                String[] pro = problem.split(" ");
                time[j] = Integer.valueOf(pro[0]);
                score[j] = Integer.valueOf(pro[1]);
                //System.out.println("time"+time[j] + ", score:" + score[j]);
            }
            int res = getResult(n, h, p, score, time);
            if (res == -1)
                System.out.println("NO");
            else
                System.out.println("YES " + res);
        }

    }

}

2.无重复字符子集问题

Description

 

Mike is a lawyer with the gift of photographic memory. He is so good with it that he can tell you all the numbers on a sheet of paper by having a look at it without any mistake. Mike is also brilliant with subsets so he thought of giving a challange based on his skill and knowledge to Rachael. Mike knows how many subset are possible in an array of N integers. The subsets may or may not have the different sum. The challenge is to find the maximum sum produced by any subset under the condition:

The elements present in the subset should not have any digit in common.

Note: Subset {12, 36, 45} does not have any digit in common and Subset {12, 22, 35} have digits in common.Rachael find it difficult to win the challenge and is asking your help. Can youhelp her out in winning this challenge?

Input

 

First Line of the input consist of an integer T denoting the number of test cases. Then T test cases follow. Each test case consist of a numbe N denoting the length of the array. Second line of each test case consist of N space separated integers denoting the array elements.

Constraints:

1 <= T <= 100

1 <= N <= 100

1 <= array elements <= 100000

Output

 

Corresponding to each test case, print output in the new line.

Sample Input 1 

1
3
12 22 35

Sample Output 1

57

ANSWER:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Main {
  public static void main(String[] args) throws IOException 
    { 
        BufferedReader br = new BufferedReader( 
                              new InputStreamReader(System.in)); 
        int t = Integer.parseInt(br.readLine()); 
        while(t-->0)
        {   
            int n = Integer.parseInt(br.readLine()); 
            StringTokenizer st = new StringTokenizer(br.readLine());
            int[] arr=new int[n];
            for(int i=0;i<n;i++)
            arr[i]=Integer.parseInt(st.nextToken());
            int[][] dp=new int[n][1024];
            System.out.println(calc(0,0,dp,arr));
        }
    }
    public static int calc(int i,int j,int[][] dp,int[] arr)
    {
        if(i==arr.length)
        return 0;
        if(dp[i][j]!=0)
        return dp[i][j];
        int j1=j,temp,r;
        boolean flag=false;
        temp=arr[i];
        while(temp>0)
        {
            r=temp%10;
            if(((1<<r)&j)>0)
            {
                flag=true;
                break;
            }
            j1=j1|(1<<r);
            temp/=10;
        }
        if(flag)
        return dp[i][j]=calc(i+1,j,dp,arr);
        return dp[i][j]=Math.max(arr[i]+calc(i+1,j1,dp,arr),calc(i+1,j,dp,arr));
        
    }
}

3.矩阵计算

Description

 

Let's define a Series Whose recurrence formula is as follows :

C(n)= 3C(i-1) + 4C(i-2) + 5C(i-3) + 6C(i-4)

C(0)= 2

C(1)= 0

C(2)= 1

C(3)= 7

Now based on this Series a Matrix Mi,j of size nn is to be formed.The top left cell is(1,1) and the bottom right corner is (n,n). Each cell (i,j) of the Matrix contains either 1 or 0. If C( (i*j)^3 ) is odd, Mi,j is 1, otherwise, it's 0.Count the total number of ones in the Matrix.

Input

 

First Line Of the input will contain an integer 'T'- the number of test cases . Each of the next 'T' lines consists of an integer 'n'.-denoting the size of the matrix.

Constraints :

1 ≤ T ≤ 1000

1 ≤ n ≤ 1000

Output

 

For each test case, output a single Integer -the taste value fo the dish of size-n*n.

Sample Input 1 

1
2

Sample Output 1

0

ANSWER:

import java.util.Scanner;

class Main {
 public static void main (String[] args) {
     Scanner sc = new Scanner(System.in);
     int t = sc.nextInt();
     while(t-- > 0) {        
         int n=sc.nextInt();
         int odd=0;         
         for(int i = 1; i <= n; i++) {
             for(int j = 1;j <= n; j++) {
                 int r = (i * j) % 7;
                 r = (r * r * r) % 7;
                 if(r != 1 && r != 5)
                     odd++;
             }
         }         
            System.out.println(odd);                             
     }
  }
}

4.最小化初始点

Description

 

Given a grid with each cell consisting of positive, negative or no points i.e, zero points. We can move across a cell only if we have positive points ( > 0 ). Whenever we pass through a cell, points in that cell are added to our overall points. We need to find minimum initial points to reach cell (m-1, n-1) from (0, 0) by following these certain set of rules :

1.From a cell (i, j) we can move to (i+1, j) or (i, j+1).

2.We cannot move from (i, j) if your overall points at (i, j) is <= 0.

3.We have to reach at (n-1, m-1) with minimum positive points i.e., > 0.

Input

 

The first line contains an integer 'T' denoting the total number of test cases.In each test cases, the first line contains two integer 'R' and 'C' denoting the number of rows and column of array.
The second line contains the value of the array i.e the grid, in a single line separated by spaces in row major order.

Constraints:

1 ≤ T ≤ 30

1 ≤ R,C ≤ 10

-30 ≤ A[R][C] ≤ 30

Input: points[m][n] = { {-2, -3, 3},
{-5, -10, 1},
{10, 30, -5}
};

Output

 

Print the minimum initial points to reach the bottom right most cell in a separate line.

7

Explanation:
7 is the minimum value to reach destination with
positive throughout the path. Below is the path.

(0,0) -> (0,1) -> (0,2) -> (1, 2) -> (2, 2)

We start from (0, 0) with 7, we reach(0, 1)
with 5, (0, 2) with 2, (1, 2) with 5, (2, 2)with and finally we have 1 point (we needed
greater than 0 points at the end).

Sample Input 1 

1
3 3
-2 -3 3 -5 -10 1 10 30 -5

Sample Output 1

7

ANSWER:

import java.util.Scanner;

public class Main {
    static int minInitialPoints(int points[][],int R,int C) 
      { 
          // dp[i][j] represents the minimum initial points player 
          // should have so that when starts with cell(i, j) successfully 
          // reaches the destination cell(m-1, n-1) 
          int dp[][] = new int[R][C]; 
          int m = R, n = C; 
         
          // Base case 
          dp[m-1][n-1] = points[m-1][n-1] > 0? 1: 
                         Math.abs(points[m-1][n-1]) + 1; 
         
          // Fill last row and last column as base to fill 
          // entire table 
          for (int i = m-2; i >= 0; i--) 
               dp[i][n-1] = Math.max(dp[i+1][n-1] - points[i][n-1], 1); 
          for (int j = n-2; j >= 0; j--) 
               dp[m-1][j] = Math.max(dp[m-1][j+1] - points[m-1][j], 1); 
         
          // fill the table in bottom-up fashion 
          for (int i=m-2; i>=0; i--) 
          { 
              for (int j=n-2; j>=0; j--) 
              { 
                  int min_points_on_exit = Math.min(dp[i+1][j], dp[i][j+1]); 
                  dp[i][j] = Math.max(min_points_on_exit - points[i][j], 1); 
              } 
           } 
         
           return dp[0][0]; 
      } 
    
      /* Driver program to test above function */ 
      public static void main (String args[]) 
      { 
          Scanner scanner=new Scanner(System.in);
          int total=Integer.parseInt(scanner.nextLine());
          for (int k = 0; k<total; k++) {
               String[] RC=scanner.nextLine().split(" ");
               String[] p=scanner.nextLine().split(" ");
               int R=Integer.parseInt(RC[0]);
               int C=Integer.parseInt(RC[1]);
               int[][] points=new int[R][C];
               int flag=0;
               for (int i = 0; i < R; i++) {
             for (int j = 0; j <C; j++) {
               points[i][j]=Integer.parseInt(p[flag++]);
               
             }
             
           }
                 System.out.println(minInitialPoints(points,R,C)); 
        
      }
       
      } 
  }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章