Модераторы: Alx, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Решение уравнения, Х1 + 2*Х2 + 3*Х3 + 4*Х4 = N 
:(
    Опции темы
mamed05
  Дата 19.3.2009, 01:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 12.3.2009

Репутация: нет
Всего: нет



Помогите пожалуйста с задачей. 
Не могу понять алгоритм решения этой задачи.

Условие:
Сегодня Вася решал уравнение вида:
Х1 + 2*Х2 + 3*Х3 + 4*Х4 = 10
Вася нашел решение, где все Хi равны 1. Вася догадывается, что есть еще и другие решения. Он предлагает Пете сыграть в следующую игру. Вася называет некоторое целое неотрицательное число N (N<=2000). Петя, зная N, должен определить количество решений уравнения вида:
Х1 + 2*Х2 + 3*Х3 + 4*Х4 = N,
где Хi – неотрицательные целые числа.

Входные данные: единственное число N.
Выходные данные: ответ Пети.

Пример входных данных:
10
Пример выходных данных:
23 
PM MAIL   Вверх
Alternator
Дата 19.3.2009, 03:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 10.6.2007

Репутация: нет
Всего: 1



Код

for(i=0;i<round(N/1);i++)//round-округление до целого
    for(j=0;j<round(N/2);j++)
        for(k=0;k<round(N/3);k++)
            for(l=0;l<round(N/4);l++)
                {
                //подставляем i,j,k,l заместо соотвствующих Xi в уравнение и проверяем правильность уравнения
                if(i+2*j+3*k+4*l==N)
                    {
                    echo "зашибись";
                    удачных_решений=удачных_решений+1;
                    }
                }

при желании можно оптимизировать циклы, путем выделения доп переменных,и ументшения лишних итераций
писал на псевдо-коде
PM MAIL   Вверх
maxdiver
Дата 19.3.2009, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 29.1.2008
Где: Саратов

Репутация: 2
Всего: 18



Alternator
Ого! Это же будет работать 2000^4 / 24 = 10^12 операций на макс-тесте. Дайте мне такой комп, чтобы эта программа работала на нём меньше, чем несколько часов smile

Уж по крайней мере один цикл точно не нужен. Например, x1 будем всегда однозначно определять. Но и тогда получится 2000^3 / 24 = 1/3 * 10^9, что тоже будет работать довольно долго.

Зато если мы будем перебирать только X3 и X4, то останется задача вида:
X1 + 2 X2 = K
Ну как найти количество решений этой задачи, думаю, всем понятно smile
K div 2 + 1 будет это количество.

Итого решение за 2000^2 / 12 = 1/3 * 10^6, что будет летать.

Добавлено через 7 минут и 34 секунды
Можно, конечно, и динамическим программированием (D[I][J] - кол-во представлений числа I в виде первых J слагаемых той формулы, тогда ответом будет D[N][4], а из каждого состояния D[I][J] будет O(N) переходов в состояния D[I-J*K][J] для K=0..I), тоже будет решение за квадрат, но со значительно большей константой. Да и вообще, из пушки по воробьям это smile
PM MAIL WWW ICQ   Вверх
maxdiver
Дата 19.3.2009, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 29.1.2008
Где: Саратов

Репутация: 2
Всего: 18



Более интересно попытаться решить эту задачу за O(N).
Вот видимо решение такое: переберём X3, останется задача вида:
X1 + 2 X2 + 4 X4 = K
Здесь заметим, что, какое бы K мы ни выбрали, чётность числа K - 4 X4 всегда будет одной и той же (и равна чётности K). Но ответ у нас будет получаться как сумма по всем X4 = 0 ... K div 4 чисел:
(K - 4 X4) div 2 + 1
Помня о сохранении чётности, мы можем записать (K - 4 X4) div 2 = K div 2 - 2 X4, и получаем такую формулу:
СУММА по X4 = 0 ... K div 4 элементов: K div 2 - 2 X4 + 1.
Кроме констант здесь есть только простая арифметическая прогрессия по X4, уж её сумму мы можем по формулке посчитать.
Так что вроде как решение за O(N) есть...

Добавлено через 3 минуты и 32 секунды
Итоговая формулка получается такая:
для X3 = 0 ... N div 3
K = N - 3 X3
ANS += (K div 4 + 1) * (K div 2 - K div 4 + 1)

По крайней мере, на сэмпле работает smile
PM MAIL WWW ICQ   Вверх
GoldFinch
Дата 19.3.2009, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: нет
Всего: 26



Цитата(mamed05 @  19.3.2009,  01:19 Найти цитируемый пост)
Х1 + 2*Х2 + 3*Х3 + 4*Х4 = N,

Х1 + 2*Х2 + 3*Х3 + 4*Х4 = N это уравнение 3мерного пространства в 4мерном, которое пересекает оси в значениях N, N/2, N/3, N/4 допустим Xi=0 и Xj=0, получаем уравнение прямой на плоскости, a*Xk+b*Xl=N, a<b, для N=1 число решений равно b/a+1, для N=N, число решений равно N*b/a+1
дальше мне решать лень т.к. это решение достаточно очевидно
PM MAIL ICQ   Вверх
ksnk
Дата 19.3.2009, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: нет
Всего: 386



GoldFinch, Топикстартера интересуют целые решения.


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
mamed05
Дата 19.3.2009, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 12.3.2009

Репутация: нет
Всего: нет



А может здесь нужно применить дискретную математику, для более простого нахождения возможных решений. Потому что на метод перебора уйдет много времени. Но нужной формулы вспомнить не могу!
А выполнение самой программы ограничено в 0.5 с   smile 
PM MAIL   Вверх
GoldFinch
Дата 19.3.2009, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: нет
Всего: 26



ksnk, там и написано про целые решения

PM MAIL ICQ   Вверх
Akina
Дата 19.3.2009, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 2
Всего: 454



Чистая рекурсия... на каждом шаге передаём заполненные, заполняем следующую... в конце выводим... 
Вот на VBA
Код

Public N As Integer
Public x(2 To 4) As Integer
Public counter As Long

Sub main()
Dim t As Double
counter = 0
N = InputBox("Сумма?")
t = Timer
Call variants(4, 0)
Debug.Print "Сумма ="; N
Debug.Print "Количество вариантов ="; counter
Debug.Print "Затраченное время ="; Timer - t; "сек."
End Sub

Sub variants(index, currentsum)
Dim i As Integer
If index = 1 Then
  counter = counter + 1
  'Debug.Print counter, x(4), x(3), x(2), N - 4 * x(4) - 3 * x(3) - 2 * x(2)
Else
  For i = 0 To (N - currentsum) \ index
    x(index) = i
    Call variants(index - 1, currentsum + index * x(index))
  Next
End If
End Sub

Результат без компиляции
Цитата

Сумма =  1000 
Количество вариантов =  7049112 
Затраченное время =  2,984375  сек.

То же, с компиляцией
Цитата

Сумма =  1000 
Количество вариантов =  7049112 
Затраченное время =  1.500018  сек.




--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
ksnk
Дата 19.3.2009, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: нет
Всего: 386



Akina, Сюда можно вставить оптимизацию - оборвать рекурсию, когда currentsum стало больше N.

GoldFinch, b/a+1 не очень похоже на целое число smile Впрочем, там тот-же перебор, правда на пару порядков меньше...


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Akina
Дата 19.3.2009, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 2
Всего: 454



Цитата(ksnk @  19.3.2009,  14:33 Найти цитируемый пост)
Сюда можно вставить оптимизацию - оборвать рекурсию, когда currentsum стало больше N.

Ты хоть на код посмотри сначала, а? currentsum не может стать больше N.



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
maxdiver
Дата 19.3.2009, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 381
Регистрация: 29.1.2008
Где: Саратов

Репутация: 2
Всего: 18



Код
int n;
cin >> n;
long long ans = 0;
for (int x3=0; x3<=n/3; ++x3) {
    int k = n - x3 * 3;
    ans += (k/4 + 1) * (k/2 - k/4 + 1);
}
cout << ans << endl << clock();

Цитата
n=1000:
7049112
0
(хы, ответ совпадает с Akina, круто smile )

n=2000:
55973223
0
(что-то мне кажется, на этом тесте рекурсия будет слишком долгой smile )

n=1000000:
25755729713640
10

PM MAIL WWW ICQ   Вверх
mamed05
Дата 19.3.2009, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 12.3.2009

Репутация: нет
Всего: нет



А на Pascal это как будет выглядеть?  smile 
PM MAIL   Вверх
Akina
Дата 19.3.2009, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 2
Всего: 454



Цитата(maxdiver @  19.3.2009,  15:06 Найти цитируемый пост)
что-то мне кажется, на этом тесте рекурсия будет слишком долгой 

Да. Но универсальной... хорошо, что в конкретной задаче именно 1-2-3-4, а не какое-нить 2-5-6-11-13-16-23...
Хотя и не Аккерман.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Интересные и занимательные задачи по программированию | Следующая тема »


 




[ Время генерации скрипта: 0.0673 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.