Good solution! I have a similar idea in C++. Another optimization is that when rows >= n+1, there will be two rows starting with the same word, i.e., the sequence repeats with a cycle. We can have a mathematical solution for large rows.

The run time is O(n^2), even for very large rows and cols. The current run time is 3 ms, beats 96%.

class Solution {
public:
int wordsTyping(vector<string>& sentence, int rows, int cols) {
// length is total length of sentence, including " ", for the case of large cols
int n = sentence.size(), length = 0;
// len is size of each string, dp is repeated sentence times by start of row i
// mp indicates which word of the sentence is used at the start of row i
// By at most n+1 row, we will have repeated word at the start of row
vector<int> len(n, 0), dp(n+1, 0), mp(n, -1);
for (int i = 0; i < n; i++) {
len[i] = sentence[i].size();
length += len[i]+1;
}
int ans = 0, cur = 0, k = 0;
for (; cur < rows; cur++) {
dp[cur] = ans;
// if kth string in sentence occurs for the second time, we have a math solution.
if (mp[k] != -1) {
// in every period rows, sentence repeated freq times
int prev = mp[k], period = cur-prev, freq = dp[cur]-dp[prev], rm = (rows-cur)%period;
return ans + (rows-cur)/period*freq + dp[prev+rm]-dp[prev];
}
// kth string at the start of current row
mp[k] = cur;
// dealing with super large cols, which is not included by test cases
ans += cols/length;
int j = 0;
while (j + len[k] <= cols%length) {
j += len[k++]+1;
if (k == n) {
ans++;
k = 0;
}
}
}
return ans;
}
};