Problem:
ぴょんぴょん川渡り
問題
ある川で,一方の岸から石の上を次々と飛び移って反対側の岸まで行くという少々危険なゲームがはやっている.
今,図 4-1 のように,石はマス目の上に存在すると考える.行の数は n である. 図 4-1 では n = 5 である.
このゲームでは,一方の岸から始めて,通常のジャンプまたは m 回以下の一行飛ばしのジャンプをして反対側の岸まで渡る.通常のジャンプとは,今いる行の一つ先の行の岸または石のどれかに飛び移ることであり,一行飛ばしのジャンプとは,今いる行の二つ先の行の岸または石のどれかに飛び移ることである.始める岸の一つ先の行は 1 行目,二つ先の行は 2 行目であり,n − 1 行目の二つ先の行,及び n 行目の一つ先の行は反対側の岸であるとする.
さて,このゲームをできるだけ安全に成し遂げるために,ジャンプの危険度というものを考えることにした.それぞれの石には,滑りやすさが定まっている.石から石へ飛び移る際のジャンプの危険度は,通常のジャンプであっても,一行飛ばしのジャンプであっても,
(今いる石の滑りやすさ + 飛び移る先の石の滑りやすさ)×(横の移動距離)
で定める.ただし,横の移動距離とは,列の番号の差である.また,岸から石へ,あるいは石から岸へ飛び移るジャンプの危険度は 0 とする.
入力として n, m,それぞれの石の位置と滑りやすさが与えられたとき,反対側の岸まで到達する際のジャンプの危険度の合計の最小値を求めるプログラムを作成せよ.与えられる入力データは必ず反対側の岸まで到達することができるようになっており,同じマス目に石は 2 個以上存在しない.
入力
入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．
入力の 1 行目には,空白を区切りとして 2 個の整数 n,m が書かれている.これは,行の数と,一行飛ばしのジャンプの許される回数を表す.n,m はそれぞれ 2 ≤ n ≤ 150, 0 ≤ m ≤ (n+1)/2　を満たす.
続く n 行には,それぞれの行にある石の情報が書かれている.i+1 行目 (1 ≤ i ≤ n)には,1 つの整数 k
i
(0 ≤ k
i
≤ 10) と,それに続き 2 × ki 個の整数が空白で区切られ書かれている.これらは,始める岸から数えて i 番目の行にある石の情報を表す.
ki はその行に存在する石の個数を表し,それに続く 2 × ki 個の整数については,2 × j - 1 個目 (1 ≤ j ≤ k
i
) の整数 x
i,j
はその行の j 個目の石の列の番号を,2 × j個目の整数 d
i,j
はその行の j 個目の石の滑りやすさをそれぞれ表す.x
i,j
,d
i,j
はそれぞれ 1 ≤ x
i,j
, d
i,j
≤1000 を満たす.
採点用データのうち, 配点の 20% 分については, n ≤ 6 を満たし,配点の別の 20%分については, m = 0 を満たす.
n, m がともに 0 のとき入力の終了を示す. データセットの数は 10 を超えない．
出力
データセットごとに, 反対側の岸まで到達する際のジャンプの危険度の合計の最小値を表す 1 つの整数を1 行に出力する.
例
図 4-2 において,石に書かれた数字はそれぞれの石の滑りやすさを表すとする.
矢印で示された順番で石を渡るとき,それぞれのジャンプの危険度は,順番に 0,
(2 + 2) × 1 = 4,(2 + 1) × 1 = 3,(1 + 4) × 2 = 10,0 であり,合計は 17 となる.
このとき,ジャンプの危険度の合計は最小となる.
  この例は１つ目の入出力例に対応している.
入出力例
入力例
5 1
2 1 3 2 2
1 3 2
1 1 7
1 2 1
1 4 4
5 0
2 1 3 2 2
1 3 2
1 1 7
1 2 1
1 4 4
0 0
出力例
17
40
上記問題文と自動審判に使われるデータは、
情報オリンピック日本委員会
が作成し公開している問題文と採点用テストデータです。

Submitted solutions:

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<tuple>
#include<functional>
using namespace std;
int n, m, a, b, c, dist[4000][100]; vector<tuple<int, int, int>>p; vector<tuple<int, int, int>>K[4000][100];
int main() {
	while (true) {
		for (int i = 0; i < 4000; i++) { for (int j = 0; j < 100; j++) { dist[i][j] = 999999999; K[i][j].clear(); } }
		cin >> n >> m; p.clear(); if (n == 0 && m == 0)break;
		for (int i = 1; i <= n; i++) {
			cin >> a; for (int j = 0; j < a; j++) { cin >> b >> c; p.push_back(make_tuple(i, b, c)); }
		}
		sort(p.begin(), p.end());
		for (int i = 0; i < p.size(); i++) {
			if (get<0>(p[i]) == 1 || get<0>(p[i]) == 2) { p.push_back(make_tuple(0, get<1>(p[i]), 0)); }
			if (get<0>(p[i]) == n || get<0>(p[i]) == n - 1) { p.push_back(make_tuple(n + 1, get<1>(p[i]), 0)); }
		}
		sort(p.begin(), p.end());
		for (int h = 0; h <= m; h++) {
			for (int i = 0; i < p.size(); i++) {
				for (int j = i + 1; j < p.size(); j++) {
					if (get<0>(p[j]) - get<0>(p[i]) == 1) {
						int rx = get<1>(p[i]), sx = get<1>(p[j]);
						int rp = get<2>(p[i]), sp = get<2>(p[j]);
						int U = abs(rx - sx)*(rp + sp);
						K[i][h].push_back(make_tuple(j, h, U));
					}
					if (get<0>(p[j]) - get<0>(p[i]) == 2) {
						int rx = get<1>(p[i]), sx = get<1>(p[j]);
						int rp = get<2>(p[i]), sp = get<2>(p[j]);
						int U = abs(rx - sx)*(rp + sp);
						K[i][h].push_back(make_tuple(j, h + 1, U));
					}
					if (get<0>(p[j]) - get<0>(p[i]) >= 3) { break; }
				}
			}
		}
		priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>>Q;
		for (int i = 0; i < p.size(); i++) {
			if (get<0>(p[i]) == 0) { Q.push(make_tuple(0, i, 0)); dist[i][0] = 0; }
		}
		while (!Q.empty()) {
			int a1 = get<0>(Q.top()), a2 = get<1>(Q.top()), a3 = get<2>(Q.top()); Q.pop();
			for (int i = 0; i < K[a2][a3].size(); i++) {
				int to1 = get<0>(K[a2][a3][i]), to2 = get<1>(K[a2][a3][i]), cost = get<2>(K[a2][a3][i]);
				if (dist[to1][to2] > a1 + cost) {
					dist[to1][to2] = a1 + cost; Q.push(make_tuple(dist[to1][to2], to1, to2));
				}
			}
		}
		int maxn = 999999999;
		for (int i = 0; i < p.size(); i++) {
			if (get<0>(p[i]) != (n + 1))continue;
			for (int j = 0; j <= m; j++)maxn = min(maxn, dist[i][j]);
		}
		cout << maxn << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 59684
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=0;i<(n);i++)

// #include <atcoder/all>
// using namespace atcoder;
// using mint=modint1000000007;

using ll=long long;
using ull=unsigned long long;
using P=pair<int,int>;
using Pl=pair<ll,ll>;
using Pd=pair<double,int>;

const ll ll_INF=1e18;
const int INF=1001001001;
const int di[]={0,1,0,-1};
const int dj[]={1,0,-1,0};

template<class T>
void chmin(T &a, T b) { a=min(a,b); }
template<class T>
void chmax(T &a, T b) { a=max(a,b); }

struct Edge{
    int to; ll cost;
    Edge(){}
    Edge(int to):to(to){};
    Edge(int to, ll cost):to(to),cost(cost){};
};

int main(){
    while(true){
        const int MAX_ROW_STONE_NUM=10;
        int n,m; cin >> n >> m;
        if(n==0 && m==0) break;

        vector<vector<P>> stones(n+2);
        REP(ni,n){
            int k; cin >> k;
            REP(ki,k){
                int x,d; cin >> x >> d;
                stones.at(ni+1).emplace_back(x,d);
            }
        }
        stones.at(0).emplace_back(0,0);
        stones.at(n+1).emplace_back(0,0);

        vector dp(n+2,vector(MAX_ROW_STONE_NUM+1,vector<int>(m+1,INF)));
        dp.at(0).at(0).at(0)=0;

        REP(ni,n+1){
            auto now_st=stones.at(ni+1);
            auto prev_st=stones.at(ni);
            REP(nj,now_st.size())REP(pj,prev_st.size()){
                auto [nx,nd]=now_st.at(nj);
                auto [px,pd]=prev_st.at(pj);

                int danger=(nd+pd)*abs(nx-px);
                if(ni==0 || ni==n) danger=0;

                REP(mi,m+1){
                    chmin(dp.at(ni+1).at(nj).at(mi),dp.at(ni).at(pj).at(mi)+danger);
                }
            }

            if(ni==n) break;

            now_st=stones.at(ni+2);
            REP(nj,now_st.size())REP(pj,prev_st.size()){
                auto [nx,nd]=now_st.at(nj);
                auto [px,pd]=prev_st.at(pj);

                int danger=(nd+pd)*abs(nx-px);
                if(ni==0 || ni==n-1) danger=0;

                REP(mi,m){
                    chmin(dp.at(ni+2).at(nj).at(mi+1),dp.at(ni).at(pj).at(mi)+danger);
                }
            }
        }

        int min_danger=INF;
        REP(mi,m+1) chmin(min_danger,dp.at(n+1).at(0).at(mi));
        cout << min_danger << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3824
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vl = vector<ll>;
using vvl = vector<vl>;
using pl = pair<ll,ll>;
using vp = vector<pl>;
#define rep(i,n) for(ll i=0;i<(ll)(n);++i)
#define reps(i,s,n) for(ll i=(s);i<(ll)(n);++i)
#define rep1(i,n) for(ll i=1;i<=(ll)(n);++i)
template<typename T>inline bool chmax(T &a,T b){return a<b?a=b,true:false;}
template<typename T>inline bool chmin(T &a,T b){return a>b?a=b,true:false;}
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define be(v) (v).begin(),(v).end()
const long long INF = 1e18;
inline ll ipow(ll x,ll p){
	ll ret=x; rep1(i,p-1) ret*=x; return ret;
}
#ifdef DEBUG
#include <debug.hpp>
#endif

bool solve(){
#ifdef DEBUG
	cout << "--- Input ---" << endl;
#endif
	ll N,M;cin>>N>>M;
	if(N==0 && M==0)return false;
	vvl X(N+2),D(N+2);
	rep1(n,N){
		ll K;cin>>K;
		rep(k,K){
			ll x,d;cin>>x>>d;X.at(n).pb(x);D.at(n).pb(d);
		}
	}

#ifdef DEBUG
	cout<<N<<" "<<M<<endl<<X<<D<<endl;
	cout << "--- Logic ---" << endl;
#endif
	ll MX=10;
	vector<vector<map<ll,ll>>> dp(N+2,vector<map<ll,ll>>(MX));
		//j.rep(i,D.at(j).size()){
			//dp.at(j).at(i)[0] = 0;
		////}
	dp.at(0).at(0)[0]=0;
	X.at(0).pb(0); D.at(0).pb(0);
	X.at(N+1).pb(0); D.at(N+1).pb(0);
	rep(n,N+1){
		rep(i,X.at(n).size()){
			for(ll m=1;m<=2 && n+m<=N+1;++m){ //reps(m,min(M)
				rep(j,X.at(n+m).size()){
					for(auto now:dp.at(n).at(i)){
#ifdef DEBUG
						cout<<"n="<<n<<" i="<<i<<" m="<<m<<" j="<<j<<"now="<<now.fi<<","<<now.se
							<<" D="<<D.at(n).at(i)<<","<<D.at(n+m).at(j)
							<<" X="<<X.at(n).at(i)<<","<<X.at(n+m).at(j)<<endl;
#endif
						if(m==2 && now.fi>=M)continue;
						if(n==0){
							dp.at(n+m).at(j)[now.fi+m-1]=0;
						}else if(n+m==N+1){
							if(dp.at(n+m).at(j).count(now.fi+m-1)){
								chmin(dp.at(n+m).at(j)[now.fi+m-1],now.se);
							}else{
								dp.at(n+m).at(j)[now.fi+m-1] = now.se;
							}
						}else{
							if(dp.at(n+m).at(j).count(now.fi+m-1)){
								chmin(dp.at(n+m).at(j)[now.fi+m-1],now.se+(D.at(n).at(i)+D.at(n+m).at(j))*abs(X.at(n).at(i)-X.at(n+m).at(j)));
							}else{
								dp.at(n+m).at(j)[now.fi+m-1] = now.se+(D.at(n).at(i)+D.at(n+m).at(j))*abs(X.at(n).at(i)-X.at(n+m).at(j));
							}
						}
#ifdef DEBUG
						cout<<dp.at(n+m).at(j)[now.fi+m-1]<<endl;
#endif
					}
				}
			}
		}
	}
	ll ans=INF;
	rep(i,MX){
		for(auto e:dp.at(N+1).at(i)){
			chmin(ans,e.se);
		}
	}
#ifdef DEBUG
	cout<<dp;
	cout << "--- Answer ---" << endl;
#endif
	cout<<ans<<endl;
	return true;
}
int main(){
	while(solve());
	return 0;
}
//cout << fixed << setprecision(9);
accuracy: 1
time_ms: 60
memory_kb: 6612
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#include <random>
using namespace std;
//#include <atcoder/all>
//using namespace atcoder;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vvvvll = vector<vvvll>;
using vvvvvll = vector<vvvvll>;
using vvvvvvll = vector<vvvvvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
using vvvvb = vector<vvvb>;
using vd = vector<double>;
using vvd = vector<vd>;
using vvvd = vector<vvd>;
using vvvvd = vector<vvvd>;
using vvvvvd = vector<vvvvd>;
#define all(A) A.begin(),A.end()
#define ALL(A) A.begin(),A.end()
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)
using pqr = priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>>;

template<class T>
bool chmax(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p < q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

template<class T>
bool chmin(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p > q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

ll gcd(ll(a), ll(b)) {
    if (b == 0)return a;
    ll c = a;
    while (a % b != 0) {
        c = a % b;
        a = b;
        b = c;
    }
    return b;
}


struct dsu {
  public:
    dsu() : _n(0) {}
    dsu(int n) : _n(n), par_size(n, -1) {}

    int merge(int a, int b) {
        int x = leader(a), y = leader(b);
        if (x == y) return x;
        if (-par_size[x] < -par_size[y]) swap(x, y);
        par_size[x] += par_size[y];
        par_size[y] = x;
        return x;
    }
    int merge(pair<ll,ll> p) {
        int a=p.first;
        int b=p.second;
        int x = leader(a), y = leader(b);
        if (x == y) return x;
        if (-par_size[x] < -par_size[y]) swap(x, y);
        par_size[x] += par_size[y];
        par_size[y] = x;
        return x;
    }

    bool same(int a, int b) {
        return leader(a) == leader(b);
    }
    bool same(pair<ll,ll> p) {
        int a=p.first;
        int b=p.second;
        return leader(a) == leader(b);
    }

    int leader(int a) {
        if (par_size[a] < 0) return a;
        return par_size[a] = leader(par_size[a]);
    }

    int size(int a) {
        return -par_size[leader(a)];
    }

    vector<vector<int>> groups() {
        std::vector<int> leader_buf(_n), gr_size(_n);
        for (int i = 0; i < _n; i++) {
            leader_buf[i] = leader(i);
            gr_size[leader_buf[i]]++;
        }
        std::vector<vector<int>> res(_n);
        for (int i = 0; i < _n; i++) {
            res[i].reserve(gr_size[i]);
        }
        for (int i = 0; i < _n; i++) {
            res[leader_buf[i]].push_back(i);
        }
        res.erase(
            remove_if(res.begin(), res.end(),
                           [&](const vector<int>& v) { return v.empty(); }),
            res.end());
        return res;
    }
  private:
    int _n;
    vector<int> par_size;
};

template <class T> std::vector<int> z_algorithm(const std::vector<T>& s) {
    int n = int(s.size());
    if (n == 0) return {};
    std::vector<int> z(n);
    z[0] = 0;
    for (int i = 1, j = 0; i < n; i++) {
        int& k = z[i];
        k = (j + z[j] <= i) ? 0 : std::min(j + z[j] - i, z[i - j]);
        while (i + k < n && s[k] == s[i + k]) k++;
        if (j + z[j] < i + z[i]) j = i;
    }
    z[0] = n;
    return z;
}

vector<int> z_algorithm(const std::string& s) {
    int n = int(s.size());
    std::vector<int> s2(n);
    for (int i = 0; i < n; i++) {
        s2[i] = s[i];
    }
    return z_algorithm(s2);
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    while(1){
        ll N,M;
        cin>>N>>M;
        if(N+M==0)return 0;
        vector<vector<pair<ll,ll>>> R(N+2);
        rep(i,1001)R[0].push_back({i,0});
        rep(i,1001)R[N+1].push_back({i,0});
        rep(i,N){
            ll K;
            cin>>K;
            R[i+1].resize(K);
            rep(k,K){
                ll X,D;
                cin>>X>>D;
                R[i+1][k]={X,D};
            }
            sort(all(R[i+1]));
        }
        vvvll DP(N+2,vvll(M+1));
        rep(m,M+1)rep(i,N+1){
            DP[i+1][m].assign(R[i+1].size(),1e18);
        }
        rep(m,M+1)rep(i,R[0].size())DP[0][m].push_back(0);
        rep(i,N+1){
            rep(m,M+1){
                rep(t,R[i+1].size()){
                    rep(r,R[i].size()){
                        chmin(DP[i+1][m][t],DP[i][m][r]+(R[i+1][t].second+R[i][r].second)*abs(R[i+1][t].first-R[i][r].first));
                    }
                    if(i!=0&&m!=M){
                        rep(r,R[i-1].size()){
                            chmin(DP[i+1][m+1][t],DP[i-1][m][r]+(R[i+1][t].second+R[i-1][r].second)*abs(R[i+1][t].first-R[i-1][r].first));
                        }
                    }
                }
            }
        }
        ll an=1e18;
        rep(m,M+1)rep(r,R[N+1].size()){
            chmin(an,DP[N+1][m][r]);
        }
        rep(m,M)rep(r,R[N].size()){
            chmin(an,DP[N][m][r]);
        }
        cout<<an<<endl;
    }
    

    
}
accuracy: 1
time_ms: 20
memory_kb: 5616
final_rank: 10

code_snippet: #include "bits/stdc++.h"

#define REP(i,num) for(ll i=0;i<(num);++i)
#define FOR(i,c,num) for(ll (i)=(c);(i)<(num);++(i))
#define LOOP(i) while(i--)
#define ALL(c) c.begin(),c.end()
#define PRINTALL(c) for(auto pitr=c.begin();pitr!=c.end();++pitr){cout<<*pitr;if(next(pitr,1)!=c.end())cout<<' ';}cout<<endl;
#define PAIRCOMP(c,comp) [](const pair<ll,ll>& lhs,const pair<ll,ll>& rhs){return lhs.c comp rhs.c;}

using namespace std;
using ll = long long;
using ull = unsigned long long;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;

constexpr ll atcoder_mod = 1e9+7;

template<typename T=ll>
T in(){ T x; cin >> x; return (x); }
template<typename T=ll,typename C=vector<T>>
C vecin(int N){ C x(N);REP(i,N){ x[i]=in<T>(); }return x; }
template<typename T=ll,size_t N>
array<T,N> arrin(){array<T,N> x;REP(i,N){ x[i]=in<T>(); }return x;}

void vout(){ cout << endl; }
template<typename Head,typename... Tail>
void vout(Head&& h,Tail&&... t){ cout << ' ' << h;vout(forward<Tail>(t)...); }
void out(){ cout << endl; }
template<typename Head,typename... Tail>
void out(Head&& h,Tail&&... t){ cout << h;vout(forward<Tail>(t)...); }

template<typename T>
bool chmax(T& a,T b){ if(a<b){ a=b;return true; }return false; }
template<typename T>
bool chmin(T& a,T b){ if(a>b){ a=b;return true; }return false; }

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	while(true){
		ll N=in(),M=in();
		if(!N && !M) break;

		vector<vvll> dp(N+1,vvll(1001,vll(M+1,1ll<<60)));
		vector<vector<pair<ll,ll>>> A(N);
		REP(i,N){
			ll K=in();
			REP(j,K){
				ll u=in()-1,v=in();
				A[i].emplace_back(u,v);
			}
		}
		for(auto& x:A[0]){
			dp[0][x.first][0]=0;
		}
		if(M>0){
			for(auto& x:A[1]){
				dp[1][x.first][1]=0;
			}
		}

		for(int n=0;n<N;n++){
			for(int i=0;i<A[n].size();i++){
				auto now = A[n][i];
				for(int m=0;m<=M;m++){
					// 飛ばさない
					if(n<N-1){
						for(int j=0;j<A[n+1].size();j++){
							auto next = A[n+1][j];
							chmin(dp[n+1][next.first][m],dp[n][now.first][m]+(now.second+next.second)*(abs(now.first-next.first)));
						}
					}
					else{
						for(int j=0;j<1001;j++){
							chmin(dp[n+1][j][m],dp[n][j][m]);
						}
					}
					// 飛ばす
					if(m<M){
						if(n<N-2){
							for(int j=0;j<A[n+2].size();j++){
								auto next = A[n+2][j];
								chmin(dp[n+2][next.first][m+1],dp[n][now.first][m]+(now.second+next.second)*(abs(now.first-next.first)));
							}
						}
						else if(n<N-1){
							for(int j=0;j<1001;j++){
								chmin(dp[n+2][j][m+1],dp[n][j][m]);
							}
						}
					}
				}
			}
		}
		ll C=1ll<<60;
		for(auto& x:dp[N]){
			for(auto& y:x){
				chmin(C,y);
			}
		}
		out(C);
	}
	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 99292
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main()
{

    //dp[i][j][k]           i行目のj個目の石に1行飛ばしk回以下で行くための危険度の最小値
    //dp[i][j][k] = min_l dp[i-1][l][k]+(d[i-1][l]+d[i][j])*(j-l)   lをi-1行目の石全体動かす
    //                    dp[i-2][l][k-1]+(d[i-2][l]+d[i][j])*(j-l) lをi-2行目の石全体動かす

    while(1){

    int n,m;
    int64_t INF = 922337203685477580;
    cin >> n >> m;
    if ((n ==0) && (m == 0)) break;
    vector <vector <pair<int,int>>> grid(n);

    for(int i=0;i< n ;i++){
        int maxj;
        cin>> maxj;
        for(int j=0;j< maxj ;j++){
            int x,d;
            cin >> x >> d;
            grid[i].push_back(make_pair(x,d));
        }
    }

    vector <vector <vector <int64_t>>> dp(n,vector <vector <int64_t>>(10,vector <int64_t>(m+1,INF)));

    for(int j=0;j< grid[0].size() ;j++)for(int k=0;k< m+1 ;k++) dp[0][j][k] = 0;
    for(int j=0;j< grid[1].size() ;j++)for(int k=1;k< m+1 ;k++) dp[1][j][k] = 0;
    

    for(int i=1;i< n ;i++){
        int maxj = grid[i].size();
        for(int j=0;j< maxj  ;j++){
            for(int k=0;k< m+1 ;k++){
                for(int jj=0;jj< grid[i-1].size() ;jj++) dp[i][j][k] = min(dp[i][j][k],dp[i-1][jj][k]+(abs(grid[i][j].first-grid[i-1][jj].first))*(grid[i][j].second+grid[i-1][jj].second));
                if ((i >= 2) && (k > 0)){for(int jj=0;jj<grid[i-2].size()  ;jj++) dp[i][j][k] = min(dp[i][j][k],dp[i-2][jj][k-1]+(abs(grid[i][j].first-grid[i-2][jj].first))*(grid[i][j].second+grid[i-2][jj].second));}
            }
        }

    }

    int64_t ans = INF;
    for(int j=0;j< grid[n-1].size() ;j++) ans = min(ans,dp[n-1][j][m]);
    if(m >= 1) for(int j=0;j< grid[n-2].size() ;j++) ans = min(ans,dp[n-2][j][m-1]);

    cout <<  ans << endl;

    }

    return 0;
 
}
accuracy: 1
time_ms: 10
memory_kb: 4048
final_rank: 5

code_snippet: #include<bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#define rep(i, x) for(ll i = 0; i < x; i++)
#define rep2(i, x) for(ll i = 1; i <= x; i++)
#define all(a) (a).begin(),(a).end()
using ll = long long;
using ld = long double;
using namespace std;
const ll INF = 1000000000000000000;
const ll mod = 1000000007;
const ll MOD = 998244353;
const ld pi = 3.141592653589793238;

signed main() {
	ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	while (true) {
		ll n, m; cin >> n >> m; m++;
		if (n == 0) { return 0; }
		vector<vector<vector<ll>>> dp(n + 1);
		typedef pair<ll, ll> p; vector<vector<p>> v(n + 1);
		rep2(i, n) {
			ll k; cin >> k;
			rep(j, k) {
				ll a, b; cin >> a >> b;
				v[i].push_back(p(a, b));
			}
			dp[i] = vector<vector<ll>>(k, vector<ll>(m + 1));
		}
		rep2(i, n) {
			rep(j, v[i].size()) {
				rep(k, m) {
					dp[i][j][k] = 1000000000000000;
				}
			}
		}
		rep(i, v[1].size()) { dp[1][i][0] = 0; }
		rep(i, v[2].size()) { dp[2][i][1] = 0; }
		for (int i = 2; i <= n; i++) {//今見てる行 O(n)
			rep(j, v[i].size()) {//今の行の石 O(10)
				rep(k, v[i - 1].size()) {//一つ前の行の石 O(10)
					rep(l, m) {//飛びジャンプ
						ll cnt = (v[i - 1][k].second + v[i][j].second) * abs(v[i - 1][k].first - v[i][j].first);
						dp[i][j][l] = min(dp[i][j][l], dp[i - 1][k][l] + cnt);
					}
				}
				rep(k, v[i - 2].size()) {//二つ前の行の石 O(10)
					rep(l, m - 1) {//飛びジャンプ
						ll cnt = (v[i - 2][k].second + v[i][j].second) * abs(v[i - 2][k].first - v[i][j].first);
						dp[i][j][l + 1] = min(dp[i][j][l + 1], dp[i - 2][k][l] + cnt);
					}
				}
			}
		}
		ll ans = INF;
		rep(i, v[n - 1].size()) {
			rep(j, m - 1) {
				ans = min(ans, dp[n - 1][i][j]);
			}
		}
		rep(i, v[n].size()) {
			rep(j, m) {
				ans = min(ans, dp[n][i][j]);
			}
		}
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3948
final_rank: 4

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
const int inf = 1012345678;
int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);
	while (true) {
		int N, M;
		cin >> N >> M;
		if (N == 0 && M == 0) break;
		vector<int> pos(N + 3), X = { 0 }, D = { 0 };
		pos[1] = 1;
		for (int i = 1; i <= N; ++i) {
			int K;
			cin >> K;
			pos[i + 1] = pos[i] + K;
			for (int j = 0; j < K; ++j) {
				int tx, td;
				cin >> tx >> td;
				X.push_back(tx);
				D.push_back(td);
			}
		}
		pos[N + 2] = pos[N + 1] + 1;
		X.push_back(0);
		D.push_back(0);
		vector<vector<int> > dp(pos[N + 2], vector<int>(M + 1, inf));
		fill(dp[0].begin(), dp[0].end(), 0);
		for (int i = 1; i <= N + 1; ++i) {
			for (int j = 1; j <= i && j <= 2; ++j) {
				for (int k = pos[i]; k < pos[i + 1]; ++k) {
					for (int x = (j == 2 ? 1 : 0); x <= M; ++x) {
						for (int l = pos[i - j]; l < pos[i - j + 1]; ++l) {
							dp[k][x] = min(dp[k][x], dp[l][x - (j == 2 ? 1 : 0)] + (i - j == 0 || i == N + 1 ? 0 : abs(X[k] - X[l]) * (D[k] + D[l])));
						}
					}
				}
			}
		}
		cout << dp.back()[M] << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3412
final_rank: 1

code_snippet: #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0;i < (int)(n);i++)
using ll = long long;
const ll MOD=1000000007;
const long long INF = 1LL << 60;
const double pi=acos(-1.0);

template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }

vector<vector<map<ll,ll>>> table;
vector<vector<pair<ll,ll>>> grid;

ll dp(ll n,ll x,ll d,ll m){
  if(m<0) return INF;
  if(n==0) return 0;
  if(n==1&&m>=1) return 0;
  if(table.at(m).at(n).count(x)) return table.at(m).at(n).at(x);
  
  table.at(m).at(n)[x]=INF;
  //n-1からの移動
  for(auto p:grid.at(n-1)){
    ll px,pd; tie(px,pd)=p;
    chmin(table.at(m).at(n).at(x),dp(n-1,px,pd,m)+(d+pd)*abs(x-px));
  }
  
  if(n<2||m<1) return table.at(m).at(n).at(x);
  //n-2からの移動
  for(auto p:grid.at(n-2)){
    ll px,pd; tie(px,pd)=p;
    chmin(table.at(m).at(n).at(x),dp(n-2,px,pd,m-1)+(d+pd)*abs(x-px));
  }
  
  return table.at(m).at(n).at(x);
}


int main()
{
  while(true){
    ll N,M; cin>>N>>M; if(N==0&&M==0) break;
    grid=vector<vector<pair<ll,ll>>>(N,vector<pair<ll,ll>>(0));
    rep(i,N){
      ll k; cin>>k;
      rep(j,k){
        ll x,d; cin>>x>>d; x--;
        grid.at(i).push_back({x,d});
      }
    }
    
    //dp
    table=vector<vector<map<ll,ll>>>(M+1,vector<map<ll,ll>>(N));
    ll ans=INF;
    for(auto p:grid.at(N-1)){
      ll x,d;tie(x,d)=p;
      chmin(ans,dp(N-1,x,d,M));
    }
    
    if(M<1) {cout<<ans<<endl; continue;}
    
    for(auto p:grid.at(N-2)){
      ll x,d; tie(x,d)=p;
      chmin(ans,dp(N-2,x,d,M-1));
    }
    
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 7316
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

int N, M;
int MapData[152][1002];
vector<pair<int, int> > StoneInfo[152];
int DpSum[152][1002][78];

const int INF = 999999999;

void solve() {
	int curRowStone, curCol, cost, minSum;

	curRowStone = StoneInfo[1].size();
	for (int i = 0; i < curRowStone; ++i) {
		curCol = StoneInfo[1][i].first;
		DpSum[1][curCol][0] = 0;
	}

	curRowStone = StoneInfo[2].size();
	for (int i = 0; i < curRowStone; ++i) {
		curCol = StoneInfo[2][i].first;
		DpSum[2][curCol][1] = 0;
	}

	for (int i = 1; i < N; ++i) {
		for (int j = 1; j < 1002; ++j) {
			for (int k = 0; k <= M; ++k) {
				if (DpSum[i][j][k] == INF) {
					continue;
				}

				curRowStone = StoneInfo[i + 1].size();
				for (int t = 0; t < curRowStone; ++t) {
					curCol = StoneInfo[i + 1][t].first;
					cost = (MapData[i][j] + StoneInfo[i + 1][t].second) * abs(j - curCol);
					DpSum[i + 1][curCol][k] = min(DpSum[i + 1][curCol][k], DpSum[i][j][k] + cost);
				}

				if (k == M || i == N - 1) {
					continue;
				}
				curRowStone = StoneInfo[i + 2].size();
				for (int t = 0; t < curRowStone; ++t) {
					curCol = StoneInfo[i + 2][t].first;
					cost = (MapData[i][j] + StoneInfo[i + 2][t].second) * abs(j - curCol);
					DpSum[i + 2][curCol][k + 1] = min(DpSum[i + 2][curCol][k + 1], DpSum[i][j][k] + cost);
				}
			}
		}
	}

	minSum = INF;
	for (int i = 0; i < 1002; ++i) {
		for (int k = 0; k <= M; ++k) {
			minSum = min(minSum, DpSum[N][i][k]);
		}
	}
	for (int i = 0; i < 1002; ++i) {
		for (int k = 0; k < M; ++k) {
			minSum = min(minSum, DpSum[N - 1][i][k]);
		}
	}
	cout << minSum << endl;
}

int main() {
	int k, col, value;

	while (cin >> N >> M, N) {
		for (int i = 0; i < 152; ++i) {
			StoneInfo[i].clear();
			for (int j = 0; j < 1002; ++j) {
				MapData[i][j] = INF;
			}
		}
		for (int i = 1; i <= N; ++i) {
			cin >> k;
			for (int j = 0; j < k; ++j) {
				cin >> col >> value;
				MapData[i][col] = value;
				StoneInfo[i].push_back({ col,value });
			}
		}
		//fill_n(&DpSum[0][0][0], N * 1002 * M, INF);
		for (int i = 0; i < 152; ++i) {
			for (int j = 0; j < 1002; ++j) {
				for (int k = 0; k < 78; ++k) {
					DpSum[i][j][k] = INF;
				}
			}
		}
		solve();
	}

	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 50132
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

int N, M;
int MapData[152][1002];
vector<pair<int, int> > StoneInfo[152];
int DpSum[152][1002][78];

const int INF = 999999999;

void solve() {
	int curRowStone, curCol, cost, minSum;

	curRowStone = StoneInfo[0].size();
	for (int i = 0; i < curRowStone; ++i) {
		curCol = StoneInfo[0][i].first;
		DpSum[0][curCol][0] = 0;
	}

	curRowStone = StoneInfo[1].size();
	for (int i = 0; i < curRowStone; ++i) {
		curCol = StoneInfo[1][i].first;
		DpSum[1][curCol][1] = 0;
	}

	for (int i = 0; i < N - 1; ++i) {
		for (int j = 0; j < 1002; ++j) {
			for (int k = 0; k <= M; ++k) {
				if (DpSum[i][j][k] == INF) {
					continue;
				}

				curRowStone = StoneInfo[i + 1].size();
				for (int t = 0; t < curRowStone; ++t) {
					curCol = StoneInfo[i + 1][t].first;
					cost = (MapData[i][j] + StoneInfo[i + 1][t].second) * abs(j - curCol);
					DpSum[i + 1][curCol][k] = min(DpSum[i + 1][curCol][k], DpSum[i][j][k] + cost);
				}

				if (k == M || i == N - 1) {
					continue;
				}
				curRowStone = StoneInfo[i + 2].size();
				for (int t = 0; t < curRowStone; ++t) {
					curCol = StoneInfo[i + 2][t].first;
					cost = (MapData[i][j] + StoneInfo[i + 2][t].second) * abs(j - curCol);
					DpSum[i + 2][curCol][k + 1] = min(DpSum[i + 2][curCol][k + 1], DpSum[i][j][k] + cost);
				}
			}
		}
	}

	minSum = INF;
	for (int i = 0; i < 1002; ++i) {
		for (int k = 0; k <= M; ++k) {
			minSum = min(minSum, DpSum[N - 1][i][k]);
		}
	}
	for (int i = 0; i < 1002; ++i) {
		for (int k = 0; k < M; ++k) {
			minSum = min(minSum, DpSum[N - 2][i][k]);
		}
	}
	cout << minSum << endl;
}

int main() {
	int k, col, value;

	while (cin >> N >> M, N) {
		for (int i = 0; i < 152; ++i) {
			StoneInfo[i].clear();
			for (int j = 0; j < 1002; ++j) {
				MapData[i][j] = INF;
			}
		}
		for (int i = 0; i < N; ++i) {
			cin >> k;
			for (int j = 0; j < k; ++j) {
				cin >> col >> value;
				--col;
				MapData[i][col] = value;
				StoneInfo[i].push_back({ col,value });
			}
		}
		//fill_n(&DpSum[0][0][0], N * 1002 * M, INF);
		for (int i = 0; i < 152; ++i) {
			for (int j = 0; j < 1002; ++j) {
				for (int k = 0; k < 78; ++k) {
					DpSum[i][j][k] = INF;
				}
			}
		}
		solve();
	}

	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 50124
final_rank: 16

code_snippet: #include<bits/stdc++.h>
#define enld '\n'
#define rep(i,n) for(int i=0; i<(n); i++)
using namespace std;
using ll = long long;
using P = pair<int,int>;
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("Ofast")
constexpr ll INF = 1e18;
constexpr int inf = 1e9;
constexpr ll mod = 1000000007;
constexpr ll mod2 = 998244353;
const double PI = 3.1415926535897932384626433832795028841971;
const int dx[6] = {1, 0, -1, 0,1,1};
const int dy[6] = {0, 1, 0, -1,1,-1};
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
// ---------------------------------------------------------------------------

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int N,M;
    cin >> N >> M;
    while(N != 0){
        vector<vector<pair<ll,ll>>> G(N);
        for(int i=0; i<N; i++){
            int k;
            cin >> k;
            for(int j=0; j<k; j++){
                int a,b;
                cin >> a >> b;
                G[i].emplace_back(a,b);
            }
        }
        ll dp[N+1][15][N];
        for(int i=0; i<N; i++){
            for(int j=0; j<G[i].size(); j++){
                for(int k=0; k<=M; k++){
                    dp[i][j][k] = INF; 
                }
            }
        }
        for(int i=0; i<G[0].size(); i++){
            dp[0][i][0] = 0;
        }
        for(int i=0; i<G[1].size(); i++){
            dp[1][i][1] = 0;
        }
        for(int i=0; i<N-1; i++){
            for(int j=0; j<G[i].size(); j++){
                for(int k=0; k<=M; k++){
                    for(int l=0; l<G[i+1].size(); l++){
                        ll cost = G[i][j].second + G[i+1][l].second;
                        ll sa = abs(G[i][j].first - G[i+1][l].first);
                        chmin(dp[i+1][l][k],dp[i][j][k]+cost*sa);
                    }
                    if(i+2<N and k<M){
                        for(int l=0; l<G[i+2].size(); l++){
                            ll cost = G[i][j].second + G[i+2][l].second;
                            ll sa = abs(G[i][j].first - G[i+2][l].first);
                            chmin(dp[i+2][l][k+1],dp[i][j][k]+cost*sa);
                        }
                    }
                }
            }
        }
        // for(int i=0; i<N; i++){
        //     for(int j=0; j<G[i].size(); j++){
        //         for(int k=0; k<=M; k++){
        //             cout << "check:" << i << " " << j << " " << k << " " << dp[i][j][k] << enld;
        //         }
        //     }
        // }
        ll ans = INF;
        for(int i=0; i<G[N-2].size(); i++){
            for(int j=0; j<M; j++){
                chmin(ans,dp[N-2][i][j]);
            }
        }
        for(int i=0; i<G[N-1].size(); i++){
            for(int j=0; j<=M; j++){
                chmin(ans,dp[N-1][i][j]);
            }
        }
        cout << ans << enld;
        cin >> N >> M;
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 5600
final_rank: 9

code_snippet: #include<bits/stdc++.h>
#define enld '\n'
#define rep(i,n) for(int i=0; i<(n); i++)
using namespace std;
using ll = long long;
using P = pair<int,int>;
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("Ofast")
constexpr ll INF = 1e18;
constexpr int inf = 1e9;
constexpr ll mod = 1000000007;
constexpr ll mod2 = 998244353;
const double PI = 3.1415926535897932384626433832795028841971;
const int dx[6] = {1, 0, -1, 0,1,1};
const int dy[6] = {0, 1, 0, -1,1,-1};
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
// ---------------------------------------------------------------------------

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll N,M;
    cin >> N >> M;
    while(N != 0){
        vector<vector<pair<ll,ll>>> G(N);
        for(int i=0; i<N; i++){
            int k;
            cin >> k;
            for(int j=0; j<k; j++){
                ll a,b;
                cin >> a >> b;
                G[i].emplace_back(a,b);
            }
        }
        ll dp[N+1][15][N];
        for(int i=0; i<N; i++){
            for(int j=0; j<G[i].size(); j++){
                for(int k=0; k<=M; k++){
                    dp[i][j][k] = INF; 
                }
            }
        }
        for(int i=0; i<G[0].size(); i++){
            dp[0][i][0] = 0;
        }
        for(int i=0; i<G[1].size(); i++){
            dp[1][i][1] = 0;
        }
        for(int i=0; i<N-1; i++){
            for(int j=0; j<G[i].size(); j++){
                for(int k=0; k<=M; k++){
                    for(int l=0; l<G[i+1].size(); l++){
                        ll cost = G[i][j].second + G[i+1][l].second;
                        ll sa = abs(G[i][j].first - G[i+1][l].first);
                        chmin(dp[i+1][l][k],dp[i][j][k]+cost*sa);
                    }
                    if(i+2<N and k<M){
                        for(int l=0; l<G[i+2].size(); l++){
                            ll cost = G[i][j].second + G[i+2][l].second;
                            ll sa = abs(G[i][j].first - G[i+2][l].first);
                            chmin(dp[i+2][l][k+1],dp[i][j][k]+cost*sa);
                        }
                    }
                }
            }
        }
        // for(int i=0; i<N; i++){
        //     for(int j=0; j<G[i].size(); j++){
        //         for(int k=0; k<=M; k++){
        //             cout << "check:" << i << " " << j << " " << k << " " << dp[i][j][k] << enld;
        //         }
        //     }
        // }
        ll ans = INF;
        for(int i=0; i<G[N-2].size(); i++){
            for(int j=0; j<M; j++){
                chmin(ans,dp[N-2][i][j]);
            }
        }
        for(int i=0; i<G[N-1].size(); i++){
            for(int j=0; j<=M; j++){
                chmin(ans,dp[N-1][i][j]);
            }
        }
        cout << ans << enld;
        cin >> N >> M;
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 5576
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;

struct edge {
    ll cost;
    int tobasu;
    int to;
    edge(){}
    edge(ll cost,int tobasu,int to):cost(cost),tobasu(tobasu),to(to){}

    bool operator<(const edge& rhs) const{
        if(cost>rhs.cost)return true;
        else if(cost<rhs.cost)return false;
        else return to<rhs.to;
    }

    edge operator+(const edge rhs){
        return edge(cost+rhs.cost,tobasu+rhs.tobasu,rhs.to);
    }
};

vector<vector<edge>> G;
vector<vector<pair<ll,pair<int,int>>>> ishi;
vector<vector<ll>> dp;

int main() {
    while(true) {
        int n,m;
        cin>>n>>m;
        if(n==0)break;

        int vt=0;
        ishi.resize(n);
        for(int i = 0;i < n;++i) {
            int k;
            cin>>k;
            for(int j = 0;j < k;++j) {
                int a;
                ll c;
                cin>>a>>c;
                ishi[i].emplace_back(c,make_pair(a,vt));
                ++vt;
            }
        }

        G.resize(vt+2);
        for(int i = 0;i < n;++i) {
            for(auto v:ishi[i]) {
                if(i!=n-1) {
                    for(auto x:ishi[i+1]) {
                        ll cost=(v.first+x.first)*abs(v.second.first-x.second.first);
                        G[v.second.second].emplace_back(cost,0,x.second.second);
                    }
                }
                else {
                    G[v.second.second].emplace_back(0,0,vt);
                }

                if(i<n-2) {
                    for(auto x:ishi[i+2]) {
                        ll cost=(v.first+x.first)*abs(v.second.first-x.second.first);
                        G[v.second.second].emplace_back(cost,1,x.second.second);
                    }
                }
                else if(i==n-2){
                    G[v.second.second].emplace_back(0,1,vt);
                }
            }
        }

//cerr<<"OK"<<endl;

        priority_queue<edge> pq;
        for(auto v:ishi[0]) {
            pq.emplace(0LL,0,v.second.second);
        }

        for(auto v:ishi[1]) {
            pq.emplace(0LL,1,v.second.second);
        }

        dp.assign(vt+1,vector<ll>(m+1,1000000000000LL));

        while(!pq.empty()) {
            auto t=pq.top();
//cerr<<"cost:"<<t.cost<<" tobasu:"<<t.tobasu<<" to:"<<t.to<<endl;
            if(t.to==vt)break;
            pq.pop();
            for(auto v:G[t.to]) {
                auto te=t+v;
                if(te.tobasu>m)continue;
                if(dp[te.to][te.tobasu]<te.cost)continue;
                dp[te.to][te.tobasu]=te.cost;
                pq.push(te);
            }
        }

        cout<<pq.top().cost<<endl;

        G.clear();
        ishi.clear();
        dp.clear();
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 6696
final_rank: 11

code_snippet: #include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
long long int INF = 1001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000007LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}

#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()

/* do your best */


bool solve() {

  int n, m; cin >> n >> m;
  if (n == 0 and m == 0) {
    return false;
  }

  vector<vector<pair<int, int>>> info(n); // info[i] := 行 i {位置，cost}

  for (int i = 0; i < n; i++) {
    int k; cin >> k;
    for (int j = 0; j < k; j++) {
      int pos, cost; cin >> pos >> cost;
      info[i].push_back({pos, cost});
    }
  }
  
  vector<vector<vector<lint>>> dp(n, vector<vector<lint>> (1001, vector<lint> (m + 1, INF)));
  for (int j = 0; j < info[0].size(); j++) {
    int pos = info[0][j].first;
    dp[0][pos][0] = 0;
  }

  for (int j = 0; j < info[1].size(); j++) {
    int pos = info[1][j].first;
    dp[1][pos][1] = 0;
  }

  for (int i = 0; i < n - 1; i++) {
    for (int j = 0; j < info[i].size(); j++) {
      for (int k = 0; k <= m; k++) {
        // cerr << "kudan : " << dp[2][1][1] << endl;
        int curPos = info[i][j].first;
        lint cost1 = info[i][j].second;
        lint curCost = dp[i][curPos][k];

        // 普通のジャンプ
        for (int j = 0; j < info[i + 1].size(); j++) {
          int nxtPos = info[i + 1][j].first;
          lint cost2 = info[i + 1][j].second;
          lint nxtCost = (cost1 + cost2) * (lint)abs(curPos - nxtPos);
          dp[i + 1][nxtPos][k] = min(dp[i + 1][nxtPos][k], curCost + nxtCost);
        }

        // 2 段飛ばしジャンプ
        if (i + 2 < n and k < m) {
          for (int j = 0; j < info[i + 2].size(); j++) {
            int nxtPos = info[i + 2][j].first;
            // cerr << "i = " << i << ", curPos = " << curPos << ", nxtPos = " << nxtPos << endl;
            lint cost2 = info[i + 2][j].second;
            lint nxtCost = (cost1 + cost2) * (lint)abs(curPos - nxtPos);
            // cerr << "curCost = " << curCost << ", nxtCost = " << nxtCost << endl;
            // cerr << "before: " << i + 2 << " " << nxtPos << " " << k + 1 << ", " << dp[i + 2][nxtPos][k + 1] << endl;
            dp[i + 2][nxtPos][k + 1] = min(dp[i + 2][nxtPos][k + 1], curCost + nxtCost);
            // cerr << "after: " << i + 2 << " " << nxtPos << " " << k + 1 << ", " << dp[i + 2][nxtPos][k + 1] << endl;
          }
        }
      }
    }
  }

  lint ans = INF;
  for (int j = 0; j < info[n - 1].size(); j++) {
    for (int k = 0; k <= m; k++) {
      int pos = info[n - 1][j].first;
      ans = min(ans, dp[n - 1][pos][k]);
    }
  }

  for (int j = 0; j < info[n - 2].size(); j++) {
    for (int k = 0; k < m; k++) {
      int pos = info[n - 2][j].first;
      ans = min(ans, dp[n - 2][pos][k]);
    }
  }

  cout << ans << endl;
  return true;
}


int main() {
  
  while (1) {
    if (!solve()) break;
  }
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 98412
final_rank: 19

code_snippet: #include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

ll n,m;
vector<ll>  x[200],d[200];

ll get_cost(int a,int b,int c, int d_){
    if(a == 0) return 0;
    if(c == n+1) return 0;
    return (d[a][b]+d[c][d_])*abs(x[a][b]-x[c][d_]);
}

ll dp[200][200][10];
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(1){
    cin >> n >> m;
    if(n == 0) break;
    
    for(int i = 0;i < 200;i++){
        x[i] = vector<ll>(0);        d[i] = vector<ll>(0);

    }

    x[0].push_back(0);
    x[n+1].push_back(0);

    for (int i = 1;i <= n;i++){
        ll k; cin >> k;
        for (int j = 0;j < k;j++){
            ll x_,d_; cin >> x_ >> d_;
            x[i].push_back(x_);
            d[i].push_back(d_);
        }
    }

    for (int i = 0;i < 200;i++){
        for (int j = 0;j < 200;j++){
            for (int k = 0;k < 10;k++){
                dp[i][j][k] = LLONG_MAX;
            }
        }
    }

    dp[0][m][0] = 0;

    for (int i = 0;i <= n;i++){
        for (int j = 0;j <= m;j++){
            for (int k = 0;k < x[i].size();k++){
                if(dp[i][j][k] == LLONG_MAX) continue;
                //cout << i << " " << j << " " << k << endl;
                if(i != n && j != 0){
                    for (int l = 0;l < x[i+2].size();l++){
                        dp[i+2][j-1][l] = min(dp[i+2][j-1][l],dp[i][j][k]+get_cost(i,k,i+2,l));
                    }
                }
                for (int l = 0;l < x[i+1].size();l++){
                    dp[i+1][j][l] = min(dp[i+1][j][l],dp[i][j][k]+get_cost(i,k,i+1,l));
                }
            }
        }
    }

    ll ans = LLONG_MAX;
    for (int i = 0;i <= m;i++){
        ans = min(dp[n+1][i][0],ans);
    }

    cout << ans << endl;
    }

    return 0;

}
accuracy: 1
time_ms: 10
memory_kb: 6352
final_rank: 7

code_snippet: #include <algorithm>
#include <bitset>
#include <cctype>
#include <chrono>
#include <cmath>
#include <cstdio>
#include <ctime>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
using namespace std;

#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()

const int INF = 0x3f3f3f3f;
const long long LINF = 0x3f3f3f3f3f3f3f3fLL;
/*----------------------------------------*/

int main() {
  cin.tie(0); ios::sync_with_stdio(false);
  // freopen("input.txt", "r", stdin);

  while (true) {
    int n, m; cin >> n >> m;
    if (n == 0 && m == 0) break;
    vector<vector<pair<int, int>>> stone(n+3, vector<pair<int, int>>(0));
    FOR(i, 1, n+1) {
      int k; cin >> k;
      REP(j, k) {
        int x, d; cin >> x >> d;
        stone[i].push_back({x, d});
      }
    }
    FOR(j, 1, 1001) {
      stone[0].push_back({j, 0});
      stone[n+1].push_back({j, 0});
      stone[n+2].push_back({j, 0});
    }
    vector<vector<vector<int>>> dp(n+3, vector<vector<int>>(1001, vector<int>(m+1, INF)));
    FOR(j, 1, 1001) dp[0][j][0] = 0;
    REP(i, n+1) for (auto a : stone[i]) {
      for (auto b : stone[i+1]) REP(k, m+1) {
        dp[i+1][b.first][k] = min(dp[i+1][b.first][k], dp[i][a.first][k] + (a.second == 0 || b.second == 0? 0 : (a.second+b.second)*abs(a.first-b.first)));
      }
      for (auto b : stone[i+2]) REP(k, m) {
        dp[i+2][b.first][k+1] = min(dp[i+2][b.first][k+1], dp[i][a.first][k] + (a.second == 0 || b.second == 0? 0 : (a.second+b.second)*abs(a.first-b.first)));
      }
    }
    int ans = INF;
    FOR(j, 1, 1001) REP(k, m+1) ans = min({ans, dp[n+1][j][k], dp[n+2][j][k]});
    cout << ans << '\n';
  }
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 54572
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
const int N = 150;
int opt[N+2][N+2][10];
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    while(cin >> n >> m and (n or m)) {
        vector<vector<int>> pos(n + 2), slip(n + 2);
        for(int i = 1; i <= n; i++) {
            int k;
            cin >> k;
            pos[i].resize(k);
            slip[i].resize(k);
            for(int j = 0; j < k; j++) {
                cin >> pos[i][j] >> slip[i][j];
            }
        }
        for(int i = 0; i <= n + 1; i++) {
            for(int j = 0; j <= m; j++) {
                for(int cur_pos = 0; cur_pos < pos[i].size() + (i == 0 or i == n + 1); cur_pos++) {
                    if(i == 0) {
                        opt[i][j][cur_pos] = 0;    
                    } else {
                        opt[i][j][cur_pos] = lim<int>::max();
                        for(int new_pos = 0; new_pos < pos[i - 1].size() + (i - 1 == 0); new_pos++) {
                            int cost = i == n + 1 or i - 1 == 0 ? 0 : (slip[i][cur_pos] + slip[i - 1][new_pos]) * abs(pos[i][cur_pos] - pos[i - 1][new_pos]);
                            opt[i][j][cur_pos] = min(opt[i][j][cur_pos], opt[i - 1][j][new_pos] + cost);
                        }
                        if(j > 0 and i - 2 >= 0) {
                            for(int new_pos = 0; new_pos < pos[i - 2].size() + (i - 2 == 0); new_pos++) {
                                int cost = i == n + 1 or i - 2 == 0 ? 0 : (slip[i][cur_pos] + slip[i - 2][new_pos]) * abs(pos[i][cur_pos] - pos[i - 2][new_pos]);
                                opt[i][j][cur_pos] = min(opt[i][j][cur_pos], opt[i - 2][j - 1][new_pos] + cost);
                            }
                        }
                    }
                }
            }
        }
        cout << opt[n + 1][m][0] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3936
final_rank: 3

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const int INF = (int)1e9 + 7;
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

template <class T>
vector<T> make_v(size_t size, const T &init) {
    return vector<T>(size, init);
}
template <class... Ts>
auto make_v(size_t size, Ts... rest) {
    return vector<decltype(make_v(rest...))>(size, make_v(rest...));
}

int main() {
    const int MAXW = 1e3;
    int n, m;
    while (cin >> n >> m, n) {
        vector<vector<pair<int, int>>> stone(n);
        for (int i = 0; i < n; i++) {
            int k; cin >> k;
            while (k--) {
                int x, d; cin >> x >> d; x--;
                stone[i].emplace_back(x, d);
            }
        }
        auto dp = make_v(n, MAXW, m + 1, INF);
        for (int j = 0; j < MAXW; j++) {
            for (auto &p: stone[0]) dp[0][p.first][m] = 0;
            if (m) for (auto &p: stone[1]) dp[1][p.first][m - 1] = 0;
        }
        for (int i = 0; i < n - 1; i++) for (int k = 0; k <= m; k++) {
            for (auto &s: stone[i]) for (auto &t: stone[i + 1]) {
                int cost = abs(s.first - t.first) * (s.second + t.second);
                chmin(dp[i + 1][t.first][k], dp[i][s.first][k] + cost);
            }
            if (i == n - 2 || k == 0) continue;
            for (auto &s: stone[i]) for (auto &t: stone[i + 2]) {
                int cost = abs(s.first - t.first) * (s.second + t.second);
                chmin(dp[i + 2][t.first][k - 1], dp[i][s.first][k] + cost);
            }
        }
        int ans = INF;
        for (int j = 0; j < MAXW; j++) for (int k = 0; k <= m; k++) {
            if (k) chmin(ans, dp[n - 2][j][k]);
            chmin(ans, dp[n - 1][j][k]);
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 53472
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define F first
#define S second
#define pii pair<int, int>
#define eb emplace_back
#define all(v) v.begin(), v.end()
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep3(i, l, n) for (int i = l; i < (n); ++i)
#define sz(v) (int)v.size()
#define inf (int)(1e9+7)
#define abs(x) (x >= 0 ? x : -(x))
#define ceil(a, b) a / b + !!(a % b)
template<typename T1, typename T2> inline void chmin(T1 &a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1 &a, T2 b) { if (a < b) a = b; }
template<typename T> T pow(T a, int b) { return b ? pow(a * a, b / 2) * (b % 2 ? a : 1) : 1; }
template<typename T> T gcd(T a, T b) { if (b == 0) return a; return gcd(b, a % b); }







int main() {
    
    const ll INF = 1e18;
    const int A = 170, B = 15, C = 80;
    int n, m;

    while (cin >> n >> m && n) {
        ll dp[A][B][C]; // 行, その行の石, 何回とばししたか
        vector<pii> v[170];
        
        rep(i, n) {
            int k;
            cin >> k;
            rep(j, k) {
                int col, val;
                cin >> col >> val;
                v[i].eb(col, val);
            }
        }
        
        fill_n(**dp, A * B * C, INF);
        rep(j, 15) dp[0][j][0] = 0;
        rep(j, sz(v[1])) dp[1][j][1] = 0;
        
        rep(i, n - 1) {
            
            rep(k, sz(v[i])) {
                rep(l, m + 1) {
                    rep(j, sz(v[i + 1])) {
                        ll cost = (v[i + 1][j].S + v[i][k].S) * abs(v[i + 1][j].F - v[i][k].F);
                        chmin(dp[i + 1][j][l], dp[i][k][l] + cost);
                        // if (dp[i + 1][j][l] == 5198) cout << v[i + 1][j].F << " " << v[i + 1][j].S << " " << v[i][k].F << " " << v[i][k].S << endl;
                    }
                    if (i <= n - 3 && l <= m - 1) {
                        // if (l == 2) cout << i << " " << k << " " << l << endl;
                        rep(j, sz(v[i + 2])) {
                            
                            ll cost = (v[i + 2][j].S + v[i][k].S) * abs(v[i + 2][j].F - v[i][k].F); // 後ろのi + 1にしてた!!
                            
                            if (dp[i + 2][j][l + 1] > dp[i][k][l] + cost) {
                                chmin(dp[i + 2][j][l + 1], dp[i][k][l] + cost);
                                // if (dp[i + 2][k][l + 1] == 27027) cout << i + 2 << " " << k << " " << l + 1 << " " << dp[i][k][l] << " " << cost << " " << endl;
                            }
                            
                        }
                    }
                }
            }
        }
        
        ll ans = INF;
        rep(j, B) rep(k, m + 1) chmin(ans, dp[n - 1][j][k]);
        
        rep(j, B) rep(k, m) chmin(ans, dp[n - 2][j][k]); // これ忘れてた
        
        
        cout << ans << '\n';
        
        
        // cout << dp[2][0][1] << endl;

        /*
        rep(i, n) {
            cout << endl << "i " << i << endl;
            rep(j, B) {
                cout << "j " << j << endl;
                rep(k, m + 1) cout << dp[i][j][k] << " "; cout << endl;
            }
        }*/
         
    }
    
}
accuracy: 1
time_ms: 10
memory_kb: 4644
final_rank: 6