thecasuist's blog

By thecasuist, history, 6 years ago, In English

Hi everyone. I am fairly new to programming. I would be grateful if anyone could provide a counter test case to a solution I had attempted to implement for the problem "Stones" of AtCoder Educational DP Contest.

For the sake of convenience, I have attached the screenshot of the problem here.

My approach was as follows:

declare a dp table consisting of boolean values (initialised to 0) [dimension (n rows & k+1 columns) The definition of my dp state is as follows:

dp[i][j] ==> State of the situation when there are j stones and I am considering [A0, A1, ... Ai] choices of taking the stones

In a nutshell I am attempting to take the OR of the result dp[i-1][j] & (if j >= a[i]) !(dp[i][j-a[i]])

SOURCE CODE:

#include <bits/stdc++.h>
using namespace std;
 
void test(vector<int> &a, int k){
	bool dp[a.size()][k+1];
	memset(dp, 0, sizeof(dp));
	int n = a.size();
	for(int i = a[0]; i <= k; i++){
		dp[0][i] = !(dp[0][i-a[0]]);
	}
	for(int i = 1; i < a.size(); i++){
		for(int j = 1; j <= k; j++){
			bool taken = 0, ignored = 1;
			if(j &mdash; a[i]>=0){
				taken = !(dp[i][j-a[i]]);
			}
			ignored = dp[i-1][j];
			dp[i][j] = taken||ignored;
		}
	}
	if(dp[n-1][k]){
		cout << "First" << endl;
	}
	else{
		cout << "Second";
	}
	return;
}
 
int main(){
	int n, k;
	cin >> n >> k;
	vector<int> a(n);
	for(int i =0 ; i < n; i++){
		cin >> a[i];
	}
	test(a, k);
	return 0;
}
  • Vote: I like it
  • +2
  • Vote: I do not like it

| Write comment?
»
6 years ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

I think the issue with your solution is the order in which you find the winning situations. Instead of restricting the possible moves, you should find if you can win with 1 stone (with any possible moves), then with 2, 3, ... , k. btw this can be done with a 1-dimensional dp array, with k+1 elements, instead of a 2d one.

The following code gives AC: