如果我使用参考变量
int &ret = buffer[balance];
在解决在线判断问题时,不会发生超时(限制:2s)。
当我使用常规变量时,
int ret = buffer[balance];
发生超时,我想知道为什么。
这是我的使用引用变量的代码
#define INF 123456789
int coins[100]; // 사용가능한 동전들
int n; // 동전 가짓수
int k; // 총 합
int buffer[10001]; // 금액에 맞는 최소값
int check(int balance) {
if (balance < 0)
return INF;
if (balance == 0)
return 0;
int &ret = buffer[balance];
if (ret != -1)
return ret;
ret = INF;
// 가능한 모든 코인에 대해서 반복
for (int i = 0; i < n; i++) {
ret = min(check(balance - coins[i]) + 1, ret);
}
return ret;
}
int main() {
// initialization
memset(buffer, -1, sizeof(buffer));
cin >> n >> k;
for (int i = 0; i < n; i++) {
scanf_s("%d", &coins[i]);
}
int ret = check(k);
if (ret == 0 || ret == INF)
ret = -1;
cout << ret << endl;
return 0;
}
使用通用变量
int check(int balance) {
if (balance < 0)
return INF;
if (balance == 0)
return 0;
int ret = buffer[balance];
if (ret != -1)
return buffer[balance];
ret = INF;
// 가능한 모든 코인에 대해서 반복
for (int i = 0; i < n; i++) {
ret = min(check(balance - coins[i]) + 1, ret);
}
if(ret < INF)
buffer[balance] = ret;
return ret;
}
int main() {
// initialization
memset(buffer, -1, sizeof(buffer));
cin >> n >> k;
for (int i = 0; i < n; i++) {
scanf("%d", &coins[i]);
}
int ret = check(k);
if (ret == 0 || ret == INF)
ret = -1;
cout << ret << endl;
return 0;
}
这是使用参考的反汇编代码
int &ret = buffer[balance];
000B1B4B mov eax,dword ptr [balance]
000B1B4E lea ecx,buffer (0BB2D0h)[eax*4]
000B1B55 mov dword ptr [ret],ecx
if (ret != -1)
000B1B58 mov eax,dword ptr [ret]
000B1B5B cmp dword ptr [eax],0FFFFFFFFh
000B1B5E je check+5Ch (0B1B6Ch)
return buffer[balance];
000B1B60 mov eax,dword ptr [balance]
000B1B63 mov eax,dword ptr buffer (0BB2D0h)[eax*4]
000B1B6A jmp check+0C2h (0B1BD2h)
ret = INF;
000B1B6C mov eax,dword ptr [ret]
000B1B6F mov dword ptr [eax],75BCD15h
// 가능한 모든 코인에 대해서 반복
for (int i = 0; i < n; i++) {
000B1B75 mov dword ptr [ebp-14h],0
000B1B7C jmp check+77h (0B1B87h)
000B1B7E mov eax,dword ptr [ebp-14h]
000B1B81 add eax,1
000B1B84 mov dword ptr [ebp-14h],eax
000B1B87 mov eax,dword ptr [ebp-14h]
000B1B8A cmp eax,dword ptr [n (0BB2C8h)]
000B1B90 jge check+0BDh (0B1BCDh)
ret = min(check(balance - coins[i]) + 1, ret);
000B1B92 mov eax,dword ptr [ebp-14h]
000B1B95 mov ecx,dword ptr [balance]
000B1B98 sub ecx,dword ptr coins (0BB138h)[eax*4]
000B1B9F push ecx
000B1BA0 call check (0B1393h)
000B1BA5 add esp,4
000B1BA8 add eax,1
ret = min(check(balance - coins[i]) + 1, ret);
000B1BAB mov dword ptr [ebp-0E0h],eax
000B1BB1 mov edx,dword ptr [ret]
000B1BB4 push edx
000B1BB5 lea eax,[ebp-0E0h]
000B1BBB push eax
000B1BBC call std::min<int> (0B12FDh)
000B1BC1 add esp,8
000B1BC4 mov ecx,dword ptr [ret]
000B1BC7 mov edx,dword ptr [eax]
000B1BC9 mov dword ptr [ecx],edx
}
000B1BCB jmp check+6Eh (0B1B7Eh)
return ret;
000B1BCD mov eax,dword ptr [ret]
000B1BD0 mov eax,dword ptr [eax]
}
使用通用变量
int ret = buffer[balance];
00EF1B52 mov eax,dword ptr [balance]
00EF1B55 mov ecx,dword ptr buffer (0EFB2D0h)[eax*4]
00EF1B5C mov dword ptr [ret],ecx
if (ret != -1)
00EF1B5F cmp dword ptr [ret],0FFFFFFFFh
00EF1B63 je check+61h (0EF1B71h)
return buffer[balance];
00EF1B65 mov eax,dword ptr [balance]
00EF1B68 mov eax,dword ptr buffer (0EFB2D0h)[eax*4]
00EF1B6F jmp check+0C1h (0EF1BD1h)
ret = INF;
00EF1B71 mov dword ptr [ret],75BCD15h
// 가능한 모든 코인에 대해서 반복
for (int i = 0; i < n; i++) {
00EF1B78 mov dword ptr [ebp-18h],0
00EF1B7F jmp check+7Ah (0EF1B8Ah)
00EF1B81 mov eax,dword ptr [ebp-18h]
00EF1B84 add eax,1
00EF1B87 mov dword ptr [ebp-18h],eax
00EF1B8A mov eax,dword ptr [ebp-18h]
00EF1B8D cmp eax,dword ptr [n (0EFB2C8h)]
00EF1B93 jge check+0BEh (0EF1BCEh)
ret = min(check(balance - coins[i]) + 1, ret);
00EF1B95 mov eax,dword ptr [ebp-18h]
00EF1B98 mov ecx,dword ptr [balance]
00EF1B9B sub ecx,dword ptr coins (0EFB138h)[eax*4]
00EF1BA2 push ecx
00EF1BA3 call check (0EF1393h)
00EF1BA8 add esp,4
ret = min(check(balance - coins[i]) + 1, ret);
00EF1BAB add eax,1
00EF1BAE mov dword ptr [ebp-0E4h],eax
00EF1BB4 lea edx,[ret]
00EF1BB7 push edx
00EF1BB8 lea eax,[ebp-0E4h]
00EF1BBE push eax
00EF1BBF call std::min<int> (0EF12FDh)
00EF1BC4 add esp,8
00EF1BC7 mov ecx,dword ptr [eax]
00EF1BC9 mov dword ptr [ret],ecx
}
00EF1BCC jmp check+71h (0EF1B81h)
return ret;
00EF1BCE mov eax,dword ptr [ret]
}
感谢您的阅读。请帮助我!
答案 0 :(得分:0)
当ret
是引用时,您正在通过引用修改数组,并且代码等效于
int check(int balance) {
if (balance < 0)
return INF;
if (balance == 0)
return 0;
if (buffer[balance] != -1)
return buffer[balance];
buffer[balance] = INF;
for (int i = 0; i < n; i++) {
buffer[balance] = min(check(balance - coins[i]) + 1, buffer[balance]);
}
return buffer[balance];
}
如果ret
不是引用,则永远不会更新数组,因此ret != -1
永远不会为真。
答案 1 :(得分:0)
使用引用时,将使用相同的堆对象。
我快速得出结论,让您了解参考的外观:
如果您想了解更多信息,请阅读这篇文章:Ref and Pointers