# Generate best house rental plan

In a city, the rents of apartments change every month according to the demand. If there are x apartments in the city, all the rents for 12 months are given for each apartment and also x one time relocation prices are given(Applies when you move from one apartment to other in the first month). If a person comes to this city and wants to rent an apartment, optimize the rental cost for whole year by generating a month wise plan on where he must stay each month?

```#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long int  ull;
typedef long long int  ll;
#define pb push_back
#define mp make_pair
#define fr freopen("input.in", "r", stdin)
#define fw freopen("output.out", "w", stdout)
#define MX 1000
int rent[13][MX];// To Store the monthly rent of each apartment
int dp[13][MX];
int cost[MX]; //To Store the  one realocation  prize
int x;	//  x is number of  apartments
int solve(int current,int pst,int month)
{
if(month==12)// base case
{
if(current==pst)//if we want to stay in the same apartment
{
return rent[month][current];
}
else //if we want to go to the differnet apartment,then we have to give the realocation prize
return cost[current]+rent[month][current];
}
if(dp[month][current]!=0)
{
if(current==pst)
return dp[month][current];
else
return cost[current]+dp[month][current];
}
int mx=-1;
int temp;
for(int i=1;i<=x;i++)
{
temp=solve(i,current,month+1);
if(temp>mx)
mx=temp;
}
return 	dp[month][current]=mx+rent[month][current];

}
int main()
{

/*
Take here all the inputs
*/
int mx=-1,temp;
for(int i=1;i<=x;i++)
{
temp=solve(i,i,1);
if(temp>mx)
mx=temp;
}
cout<<mx<<endl;;
}```

DP Solution

```public class BestHouseRentalPlan {

private static int generateBestHouseRentalPlan(int aprtRent[][], int reloc[]) {
int s[] = new int[12];
int noRelocation[] = new int[aprtRent.length];

int min = Integer.MAX_VALUE;
int cx = 0; // current apartment index
int tcx = 0; // temporary current apartment index

for (int m=0; m<12; ++m) {
s[m] = Integer.MAX_VALUE;
cx = tcx;
for (int x=0; x<aprtRent.length; ++x) {
if (m == 0) { // First month stay in the apartment where rent is minimum
min = aprtRent[x][0];
if (min < s[m]) {
s[m] = min;
tcx = cx = x;  //store which apartment you are staying
}
} else {
if (s[m] > s[m-1] + aprtRent[cx][m]) { //every month compare current apartment
s[m] = s[m-1] + aprtRent[cx][m];   //rent with other apartment rent +
}                                      //relocation charges and choose minimum
if (aprtRent[x][m] + reloc[x] + s[m-1] < s[m]) {
s[m] = aprtRent[x][m] + reloc[x] + s[m-1];
tcx = x; // store current apartment.
}
}
noRelocation[x] += aprtRent[x][m]; //Add apartments one year rent (no relocation)
}
//   System.out.println(tcx); //uncomment to display current apartment
}

// below code handles an edge case, suppose an apartments first month rent is very high
// and relocation charge is also high, but if you rent that apartment in first month
// subsequent month rents are very less. So if one stay in that apartment without
// relocating s/he will spent less amount as rent compare to other apartments.
// check the second test set data for this scenario.
min = s[11];
for (int i=0; i<noRelocation.length; ++i) {
min = Math.min(min, noRelocation[i]);
}
return min;
}

public static void main(String[] args) {
int aprt[][] = {{30,20,30,20,10,40,60,50,60,20,70,90},
{10,20,50,20,10,40,20,50,60,20,10,100},
{40,100,10,10,10,50,20,30,20,60,10,10},
{120,110,100,90,80,70,60,50,40,30,20,10}};

int reloc[] = {20,30,60,10};

System.out.println(generateBestHouseRentalPlan(aprt, reloc));
System.out.println("");
int aprt1[][] = {{30,20,30,20,10,40,60,50,60,20,70,90},
{10,20,50,20,10,40,20,50,60,20,10,100},
{40,100,10,10,10,50,20,30,20,60,10,10},
{120,110,100,90,80,70,60,50,40,30,20,10},
{100,20,19,18,17,16,15,14,13,12,11,10}};

int reloc1[]= {20,30,60,10,100};
System.out.print(generateBestHouseRentalPlan(aprt1, reloc1));
}
}```

answered Dec 30, 2015 by Pugal
edited Jan 2, 2016

Can you please add some comments regarding variables that you are using. The code is difficult to comprehend.

What I understand from the question is following :-
Every time you change your house you have to pay reallocation fees for the new house even if you have visited the new house in some earlier month.

This is the recursive code for the problem :-

```#include<bits/stdc++.h>

using namespace std;

int a[100001][12]; // This stores the cost of living in ith apartment for all twelve
//months.
int b[12];// This stores the cost of reallocation in that house.

int x; //Numbers of apartments

int ans=INT_MAX; // This will store the optimal answer for the problem.

void solve(int j,int cost,int past)
{
if(j==12)
{
ans=min(ans,cost);
return ;
}

for(int k=0;k<x;k++)
{
if(past==k)
solve(j+1,cost+a[k][j],k);
else
solve(j+1,b[k]+cost+a[k][j],k);
}
}

int main()
{
for(int i=0;i<x;i++)
{
solve(0,a[i][0],i);
}

cout<<ans;

return 0;
}

```

```#include<bits/stdc++.h>
using namespace std;
int main()
{
int x; //no of apartments
cin>>x;
int a[x][6];
int b[6];
for(int i =0;i<x;i++)
{
for(int j =0;j<6;j++)
{cin>>a[i][j];}
}
for(int i=0;i<6;i++)
cin>>b[i];
int month[6];
memset(month,0,sizeof(month));
month[0]=10000;
for(int i =0;i<x;i++)
{
month[0]=min(month[0],a[i][0]);
}
int lastapart =0;
for(int i=1;i<6;i++)
{
int value1 =a[lastapart][i];

int q = 100000,minval=0;
int rent = 1000;
for(int j =0;j<x;j++)
{
if(a[j][i]<rent)
{
rent = a[j][i];
minval = j;
}

}
cout<<rent;
int value2=b[i]+rent;
cout<<"value1:value2"<<value1<<":"<<value2<<endl;
if(value1<value2)
{
month[i]=value1+month[i-1];
}
else{
month[i]=month[i-1]+value2;
lastapart =minval;
}
}
for(int i =0;i<6;i++)
cout<<month[i]<<" ";
}
```

answered Dec 25, 2015 by anonymous

Here's a DP solution for Y'all.  Runs in O(n^2 m) time.

```		int [][] ratesByAppt = new int[10][12];
int moveRate = 100;
for(int i=0; i<10; i++)
for(int j=0; j<12; j++)
ratesByAppt[i][j] = (int)(Math.random() * 200);

//appartments
int[][] minCosts = new int[10][12];
int[][] from = new int[10][12];
for(int n=0; n<10; n++)
minCosts[n][0] = ratesByAppt[n][0];
for(int m=1; m<12; m++)
for(int n=0; n<10; n++)
{
minCosts[n][m] = Integer.MAX_VALUE;
for(int i=0; i<10; i++)
{
int tCost = minCosts[i][m-1]+((i == n)?0:moveRate) + ratesByAppt[n][m];
if(tCost < minCosts[n][m])
{
minCosts[n][m] = tCost;
//System.out.println(n+" "+i);
from[n][m] = i;
}
}
}
int bestTCost = Integer.MAX_VALUE;
int bestEnd = 0;
for(int i=0; i<10; i++)
if(bestTCost > minCosts[i][11])
{
bestTCost = minCosts[i][11];
bestEnd = i;
}
System.out.println(bestTCost + " " + bestEnd);
String DPAns = "";
for(int i=11; i>=0; i--)
{
DPAns = bestEnd + " " + DPAns;
bestEnd = from[bestEnd][i];
}
System.out.println(DPAns);```

answered Mar 15, 2016 by J