动态规划问题练习

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值