what is the subproblem here and how it is being calculated - dynamic-programming

N exams numbered from 1 to N are going be held at Geekland state university. Geek is a renowned professor at the university and therefore is given the task to design the datesheet for exams. Datesheet must be made in such a way that total number of holidays in the datesheet is exactly K i.e. sum of holidays given for each exam is exactly K. Moreover, no exam should have more than M holidays. Two datesheets are considered different if number of holidays for a particular exam in both the datesheets is different. Find number of valid datesheets Geek can choose from. As answer can be very large, find it modulo 10^9 + 7.
solution:
int datesheets(int N, int K, int M){
int mod = 1000000007;
vector<vector<int>> dp(N+1, vector<int>(K+1, 0));
for(int i = 0; i <= N; i++)
dp[i][0] = 1;
for(int i = 1; i <= N; i++)
{
for(int j = 1; j <= K; j++)
{
dp[i][j] += dp[i-1][j];
dp[i][j] %= mod;
dp[i][j] += dp[i][j-1];
dp[i][j] %= mod;
if(j-M>0)
{
dp[i][j] = dp[i][j] - dp[i-1][j-M-1] + mod;
dp[i][j] %= mod;
}
}
}
return dp[N][K];
}

Related

How to loop for a variable amount in verilog?

In any hardware definition language, I know we can't declare a loop to loop over some circuits for some variable n times, instead we need to loop for a fixed value.
So I wanted to ask, if I have the following snippets of code:
I'm writing some sort of pseudocode in verilog, and this is an unfinished code.
input [7-1:0] note_switch;
reg[7-1:0] varnum[7-1:0];
reg[7-1:0] limit;
wire[7-1:0] numofhigh_switch;
check_high test (numofhigh_switch, note_switch);
always#(posedge octave) begin
if(octave) begin
for(count = 0; count < numofhigh_switch; count = count + 1) begin
varnum[numofhigh_switch + count] <= varnum[count] << 7;
end
end else begin
for(count = 0; count < numofhigh_switch; count = count + 1) begin
varnum[numofhigh_switch + count] <= varnum[numofhigh_switch + count];
end
end
end
I wanted to make something resembling like this, but again I know this will not work in a hardware description language, so how should I write so I can get the effect of rolling the for loop?
Actually, synthesis tools need to statically determine the maximum possible number of loops, not just a fixed number. You can do this a number of ways
Put the maximum into the conditional expression
for(count = 0; count < numofhigh_switch && count < 8; count = count + 1) begin
varnum[numofhigh_switch + count] <= varnum[count] << 7;
end
Use a conditional branching statement inside the loop
for(count = 0; count < 8; count = count + 1)
if (count < numofhigh_switch) begin
varnum[numofhigh_switch + count] <= varnum[count] << 7;
end
In SystemVerilog you can use a break statement.
for(count = 0; count < 8; count = count + 1) begin
if (count >= numofhigh_switch) break;
varnum[numofhigh_switch + count] <= varnum[count] << 7;
end

Getting segmentaition fault with subset dp problem

Given a set of numbers, check whether it can be partitioned into two subsets such that the sum of elements in both subsets is same or not
I am getting segmentation fault in C++(g++ 5.4) with a this problem.
This is where i submitted my solution in C++
https://practice.geeksforgeeks.org/problems/subset-sum-problem/0
I am checking if the array can be divided into two parts with equal sum. So I am just checking if there exists a subset with sum equal to half the sum of the array
I have implemented the below logic with dynamic programming
Let dp[i][j] denote yes or no whether a subset with sum j is possible to form with elements in the range [0, i](both inclusive) where i is 0-based index. I have done nothing new with this traditional problem. But I am getting segmentation fault. The program is giving correct output for small test cases. What mistake have I made
I haven't used any comments because I have done nothing new. Hope it is understandable.
#include <iostream>
#include <bits/stdc++.h>
#include<cstdio>
#define ll long long int
using namespace std;
bool isVowel(char c){
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
bool isLower(char c){
return 97 <= c && c <= 122;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cout << setprecision(10);
ll t, n;
cin >> t;
while (t--) {
cin >> n;
ll a[n];
ll sum = 0;
for (ll i = 0; i < n; i++) {
cin >> a[i];
sum += a[i];
}
if (sum % 2) {
cout << "NO" << '\n';
continue;
}
sum /= 2;
ll dp[n][sum + 1];
for (ll i = 0; i < n; i++) {
for(ll j = 0; j < sum + 1; j++) {
dp[i][j] = 0;
}
}
for (ll i = 0; i < n; i++) {
dp[i][a[i]] = 1;
dp[i][0] = 1;
}
for (ll i = 1; i < n; i++) {
for (ll j = 1; j < sum + 1; j++){
if (j - a[i] > 0) {
dp[i][j] = dp[i - 1][j - a[i]];
}
dp[i][j] |= dp[i - 1][j];
}
}
cout << (dp[n - 1][sum] ? "YES" : "NO") << '\n';
}
}
The segmentation fault is due to
ll dp[n][sum + 1];
Even though the constraints say 1 <= N<= 100, 0 <= arr[i]<= 1000, the test cases used are probably much larger, so ll dp[n][sum + 1] will end up taking some serious stack memory, use
bool dp[n][sum + 1];
It should work fine.
On a side note, avoid using ll randomly, use them according to the constraints.

MIPS. Count an amount of each ascii symbol in a string.

I am trying to complete a task in MIPS.
It is needed to compare 2 strings in the next way: to count a number of each ascii symbol from 1 to 255 in both strings and and compare values for each symbol.
For a moment i have wrote piece of pseudo code in java just to visualize a problem. The part that i can't understand is how can i make a "search" of each ascii character in a string.
// array allAscii that suppose to contain all ascii symbols (i have made it
containing all zeros bacause in this java code it is not that much important)
int[] allAscii = new int[255]
String s1 = "ascii."; // first string
String s2 = "asciiz,"; // second string
int difference = 0;
for(int i = 0; i< allAscii.length; i++){
int count1 = 0; //counter for the character of the string1
int count2 = 0; //counter for the character of the string1
for(int k = 0; k<s1.length(); k++){
if( s1.charAt(k) == allAscii[i]) count1++;
}
for(int l = 0; l<s2.length(); l++){
if( s2.charAt(l) == allAscii[i]) count2++;
}
difference += Math.abs(count1- count2);
}
so as the result for strings "ascii." and "asciiz,"
symbols from 0 to 43: count1 = 0; count2 = 0; difference = 0;
',': count1 = 0; count2 = 1; difference = 1;
'.': count1 = 1; count2 = 0; difference = 1;
symbols from 47 to 96: count1 = 0; count2 = 0; difference = 0;
'a': count1 = 1; count2 = 1; difference = 0;
'c': count1 = 1; count2 = 1; difference = 0;
'i': count1 = 2; count2 = 2; difference = 0;
's': count1 = 1; count2 = 1; difference = 0;
'z': count1 = 0; count2 = 1; difference = 1;
and so on....
it is non needed to store amount of each letter. i need just to accumulate variable difference but i should run through ALL ascii symbols

In Verilog, how do I use a variable in logic

Say I have the following code:
genvar i,j;
generate
for(i = 0; i < MAX; i = i + 1) begin: gen_blah
for(j = 0; j < MAX; j = j + 1) begin: gen_foo
assign match[i] = entry[j] = i;
end
end
endgenerate
Is this a synthesizable expression? It seems like it should be since this will just unroll out into a bunch of compare-to-constant assignments. If not, how would I write this to accomplish that?
No. Imagine unrolling this and typing it out by hand. The fist two lines would cause a multiply driven net:
assign match[0] = (entry[0] == 0);
assign match[0] = (entry[1] == 0);
However, if you get rid of the generates and do this with loops inside an always block then it will work:
always_comb begin
for(int i = 0; i < MAX; i = i + 1) begin: gen_blah
for(int j = 0; j < MAX; j = j + 1) begin: gen_foo
match[i] = (entry[j] == i);
end
end
end
Inside this block you get multiple assignments to the same value but the last one "wins". I'm not sure what you are trying to accomplish with your code, so this might not actually perform the function you are looking for. If you are trying to see if any of the entries equal i then you should change it to:
always_comb begin
for(int i = 0; i < MAX; i = i + 1) begin: gen_blah
match[i]=0;
for(int j = 0; j < MAX; j = j + 1) begin: gen_foo
match[i] = match[i] || (entry[j] == i);
end
end
end

time command shows user time greater than real time

I have more or less the same question as
linux time command resulting real is less than user
and
user time larger than real time
but can't post a comment on those questions.
When I run the non-multi-threaded program given below, I occasionally get user time greater than real time with both /usr/bin/time and bash's builtin time. I don't see anything that might use a different core. Is rand() somehow the culprit? How? Thanks!
#include <stdio.h>
#include <stdlib.h>
#define N 100
#define MM_MAX 50000
int
main(int ac, char **av)
{
unsigned int i, j, k, n;
int A[N][N], B[N][N], C[N][N];
if (ac != 2) {
fprintf(stderr, "Usage: matmul <seed>");
exit(1);
}
srand((unsigned int) atoi(av[1]));
for (n = 0; n < atoi(av[1]); n++) {
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
A[i][j] = rand() % MM_MAX;
B[i][j] = rand() % MM_MAX;
}
}
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
C[i][j] = 0;
for (k = 0; k < N; k++) {
C[i][j] += A[i][k] * B[k][j];
}
printf("%7d ", C[i][j]);
}
putchar('\n');
}
}
return 0;
}

Resources